BZOJ 3529 数表(莫比乌斯反演)
http://www.lydsy.com/JudgeOnline/problem.php?id=3529
思路:令F(i)为i的约数和,
1<=x<=n,1<=y<=m
G(i)为i|gcd(x,y)的个数
g(i)为i=gcd(x,y)的个数
G(i)=floor(n/i)*floor(m/i)
g(i)=Σu(d/i)*G(d) (i|d)
F(i)可以用线性筛O(n)处理
ans=(1<=i<=min(n,m)) Σg(i)*F(i)=Σ F(i)*ΣG(d)*u(d/i) (i|d)
=(1<=d<=min(n,m)) ΣG(d)* Σ(i|d) u(d/i)*F(i)
1 #include<algorithm> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstring> 5 #include<iostream> 6 #define ll long long 7 #define inf 0x7fffffff 8 std::pair<int,int>f[200005]; 9 struct node{ 10 int n,m,id,a; 11 }q[200005]; 12 int mx,v[200005],p[200005],mark[200005],mul[200005],ans[200005]; 13 int lowbit(int x){ 14 return x&(-x); 15 } 16 int read(){ 17 char ch=getchar();int t=0,f=1; 18 while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();} 19 while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();} 20 return t*f; 21 } 22 int Read(){ 23 char ch=getchar();ll t=0,f=1; 24 while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();} 25 while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();} 26 return t*f; 27 } 28 bool cmp(node a,node b){ 29 return a.a<b.a; 30 } 31 void add(int x,int y){ 32 for (int i=x;i<=mx;i+=lowbit(i)){ 33 v[i]+=y; 34 } 35 } 36 int query(int x){ 37 int res=0; 38 if (x==0) return 0; 39 for (int i=x;i;i-=lowbit(i)){ 40 res+=v[i]; 41 } 42 return res; 43 } 44 void init(){ 45 mul[1]=1; 46 for (int i=2;i<=mx;i++){ 47 if (!mark[i]) { 48 p[++p[0]]=i; 49 mul[i]=-1; 50 } 51 for (int j=1;j<=p[0]&&i*p[j]<=mx;j++){ 52 mark[i*p[j]]=1; 53 if (i%p[j]) mul[i*p[j]]=mul[i]*(-1); 54 else { 55 mul[i*p[j]]=0; 56 break; 57 } 58 } 59 } 60 for (int i=1;i<=mx;i++) 61 for (int j=i;j<=mx;j+=i) 62 f[j].first+=i; 63 for (int i=1;i<=mx;i++) f[i].second=i; 64 } 65 void solve(int k){ 66 int id=q[k].id,n=q[k].n,m=q[k].m; 67 for (int i=1,j;i<=q[k].n;i=j+1){ 68 j=std::min(n/(n/i),m/(m/i)); 69 ans[id]+=(n/i)*(m/i)*(query(j)-query(i-1)); 70 } 71 } 72 int main(){ 73 int Q=read(); 74 for (int i=1;i<=Q;i++){ 75 q[i].n=read(),q[i].m=read(),q[i].a=read();q[i].id=i; 76 if (q[i].n>q[i].m) std::swap(q[i].n,q[i].m); 77 mx=std::max(mx,q[i].n); 78 } 79 init(); 80 std::sort(q+1,q+1+Q,cmp); 81 std::sort(f+1,f+1+mx); 82 int now=0; 83 for (int i=1;i<=Q;i++){ 84 while (now+1<=mx&&f[now+1].first<=q[i].a){ 85 now++; 86 for (int j=f[now].second;j<=mx;j+=f[now].second){ 87 add(j,f[now].first*mul[j/f[now].second]); 88 } 89 } 90 solve(i); 91 } 92 for (int i=1;i<=Q;i++) 93 printf("%d\n",ans[i]&inf); 94 }