[关闭]
@xiaoziyao 2021-08-15T00:41:27.000000Z 字数 1765 阅读 620

P5655 基础数论函数练习题 解题报告

解题报告


P5655 基础数论函数练习题解题报告:

题意

给定一个长度为 的序列, 次询问一个区间的 组数据。

分析

这么小显然提示我们预处理所有答案,设 表示区间

考虑分治,当前分治到区间 ,中点为 ,那么我们要处理所有越过中点的区间的

发现我们可以根据 生成一个序列 ,满足

这个东西可以直接递推(很显然吧)

然后考虑经过 的区间的答案,我们固定左端点为 ,设当前右端点为 ,我们发现每次移动左端点的时候会让某些 失去某些质因子,也就是说我们可以在移动 的时候动态更新 的值。

具体,我们发现可以先求出 ,然后我们找这个 每一个因子是哪个位置贡献的,删去这个因子就好了,这样我们的时间复杂度就是 了。

有一个小细节,乘法需要使用玄学的快速乘,我也不知道这为什么是对的。

代码

  1. #include<stdio.h>
  2. #define int long long
  3. const int maxn=305,mod=1000000007;
  4. int T,n,q;
  5. int ans[maxn][maxn],a[maxn],b[maxn],c[maxn];
  6. int gcd(int a,int b){
  7. return b==0? a:gcd(b,a%b);
  8. }
  9. inline int getmul(int a,int b,int mod){
  10. a%=mod,b%=mod;
  11. long long res=a*b-(int)((long double)a/mod*b)*mod;
  12. return res<0? res+mod:res;
  13. }
  14. void solve(int l,int r){
  15. if(l==r){
  16. ans[l][l]=a[l]%mod;
  17. return;
  18. }
  19. int mid=(l+r)>>1;
  20. solve(l,mid),solve(mid+1,r);
  21. for(int i=mid;i>=l;i--){
  22. int prod=1;
  23. for(int j=i+1;j<=mid;j++)
  24. prod=getmul(prod,b[j],a[i]);
  25. b[i]=a[i]/gcd(a[i],prod);
  26. }
  27. for(int i=mid+1;i<=r;i++){
  28. int prod=1;
  29. for(int j=i-1;j>mid;j--)
  30. prod=getmul(prod,b[j],a[i]);
  31. b[i]=a[i]/gcd(a[i],prod);
  32. }
  33. int prod=1;
  34. for(int i=mid;i>=l;i--){
  35. prod=b[i]%mod*prod%mod;
  36. c[mid]=1;
  37. for(int j=mid+1;j<=r;j++)
  38. c[j]=getmul(c[j-1],b[j],b[i]);
  39. int g=gcd(c[r],b[i]);
  40. for(int j=r;j>mid;j--)
  41. if(c[j-1]%g){
  42. int tmp=gcd(g,c[j-1]);
  43. b[j]/=(g/tmp),g=tmp;
  44. }
  45. int PROD=prod;
  46. for(int j=mid+1;j<=r;j++){
  47. PROD=b[j]%mod*PROD%mod;
  48. ans[i][j]=PROD;
  49. }
  50. }
  51. }
  52. signed main(){
  53. scanf("%lld",&T);
  54. while(T--){
  55. scanf("%lld%lld",&n,&q);
  56. for(int i=1;i<=n;i++)
  57. scanf("%lld",&a[i]);
  58. solve(1,n);
  59. while(q--){
  60. int x,y;
  61. scanf("%lld%lld",&x,&y);
  62. printf("%lld\n",ans[x][y]);
  63. }
  64. }
  65. return 0;
  66. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注