【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     

 

posted on 2018-10-23 16:48  myx12345  阅读(244)  评论(0编辑  收藏  举报

导航