【BZOJ3529】数表(莫比乌斯反演,BIT,自然溢出)
题意:
思路:
1 #include<cstdio> 2 #include<cstring> 3 #include<string> 4 #include<cmath> 5 #include<iostream> 6 #include<algorithm> 7 #include<map> 8 #include<set> 9 #include<queue> 10 #include<vector> 11 using namespace std; 12 typedef long long ll; 13 typedef unsigned int uint; 14 typedef unsigned long long ull; 15 typedef pair<int,int> PII; 16 typedef vector<int> VI; 17 #define fi first 18 #define se second 19 #define MP make_pair 20 #define N 110000 21 #define M 41000 22 #define eps 1e-8 23 #define pi acos(-1) 24 #define oo 1e9 25 26 int flag[N],prime[N],mu[N],t[N],ans[N],mx; 27 struct node 28 { 29 int n,m,a,id; 30 }q[N]; 31 pair<int,int> F[N]; 32 33 bool operator< (node a,node b) 34 { 35 return a.a<b.a; 36 } 37 38 int lowbit(int x) 39 { 40 return x&(-x); 41 } 42 43 void add(int x,int y) 44 { 45 while(x<=mx) 46 { 47 t[x]=t[x]+y; 48 x+=lowbit(x); 49 } 50 } 51 52 int query(int x) 53 { 54 int ans=0; 55 while(x) 56 { 57 ans+=t[x]; 58 x-=lowbit(x); 59 } 60 return ans; 61 } 62 63 void calc(int k) 64 { 65 int n=q[k].n; 66 int m=q[k].m; 67 int id=q[k].id; 68 int i=1; 69 while(i<=n) 70 { 71 int x=n/i; int y=m/i; 72 int t1=n/x; int t2=m/y; 73 int pos=min(t1,t2); 74 ans[id]+=x*y*(query(pos)-query(i-1)); 75 i=pos+1; 76 } 77 } 78 79 int main() 80 { 81 freopen("bzoj3529.in","r",stdin); 82 freopen("bzoj3529.out","w",stdout); 83 int Q; 84 scanf("%d",&Q); 85 mx=0; 86 for(int i=1;i<=Q;i++) 87 { 88 scanf("%d%d%d",&q[i].n,&q[i].m,&q[i].a); 89 q[i].id=i; 90 if(q[i].n>q[i].m) swap(q[i].n,q[i].m); 91 mx=max(mx,q[i].n); 92 } 93 94 mu[1]=1; 95 int tot=0; 96 for(int i=2;i<=mx;i++) 97 { 98 if(!flag[i]) 99 { 100 prime[++tot]=i; 101 mu[i]=-1; 102 } 103 for(int j=1;j<=tot;j++) 104 { 105 int t=prime[j]*i; 106 if(t>mx) break; 107 flag[t]=1; 108 if(i%prime[j]==0) 109 { 110 mu[t]=0; 111 break; 112 } 113 mu[t]=-mu[i]; 114 } 115 } 116 for(int i=1;i<=mx;i++) 117 for(int j=i;j<=mx;j+=i) F[j].fi+=i; 118 for(int i=1;i<=mx;i++) F[i].se=i; 119 sort(q+1,q+Q+1); 120 sort(F+1,F+mx+1); 121 int j=0; 122 for(int i=1;i<=Q;i++) 123 { 124 while(j+1<=mx&&F[j+1].fi<=q[i].a) 125 { 126 j++; 127 for(int k=F[j].se;k<=mx;k+=F[j].se) 128 add(k,F[j].first*mu[k/F[j].se]); 129 } 130 calc(i); 131 } 132 for(int i=1;i<=Q;i++) printf("%d\n",ans[i]&0x7fffffff); 133 return 0; 134 } 135 136
null