解题报告:BZOJ_2154: Crash的数字表格 莫比乌斯反演

来源:互联网 发布:易语言聊天机器人源码 编辑:程序博客网 时间:2024/05/16 19:31

题目链接

题意:

给定n,m(<=1e7)求



思路:



预处理的前缀和,这样就能在时间内得出结果

总复杂度为


代码:

#include<bits/stdc++.h>using namespace std;const int mod = 20101009;const int N = 1e7+10;vector<int>pr;bool Np[N];int mu[N];int fro[N];int Fro[N];void init(int n){   Fro[1] = fro[1] = mu[1] = 1;   for(int i=2;i<=n;i++){      fro[i]=fro[i-1]+i;      if(fro[i]>=mod)fro[i]-=mod;      if(!Np[i]){         pr.push_back(i);         mu[i] = -1;      }for(int j=0;j<pr.size();j++){         int k = i * pr[j];         if(k>n)break;         Np[k] = true;         if(i%pr[j]==0){            mu[k]=0;            break;         }mu[k] = -mu[i];      }Fro[i]=Fro[i-1]+1LL*mu[i]*i*i%mod;      if(Fro[i]>=mod)Fro[i]-=mod;      else if(Fro[i]<0)Fro[i]+=mod;   }}int main(){   int n , m ;   scanf("%d%d",&n,&m);   init(max(n,m));   int ans = 0;   if(n>m)swap(n,m);   for(int g=1,lastg;g<=n;g=lastg+1){      int val = 0;      int edn = n/g , edm = m/g;      lastg = min(n/edn,m/edm);      for(int d=1,last;d<=edn;d=last+1){         int ni = edn/d , mi = edm/d;         last = min(edn/ni,edm/mi);         val += 1LL * ( fro[last] - fro[d-1]  )  *  fro[ni]  % mod * fro[mi] % mod ;         if(val>=mod)val-=mod;         else if(val<0)val+=mod;      }ans += 1LL*(Fro[lastg]-Fro[g-1]+mod)*val%mod ;      if(ans>=mod)ans-=mod;      else if(ans<0)ans+=mod;   }printf("%d\n",ans);   return 0;}



阅读全文
0 0
原创粉丝点击