bzoj 3529: [Sdoi2014]数表

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<algorithm>
  4 #define M 200009
  5 //#define N 100000
  6 using namespace std;
  7 struct data 
  8 {
  9     int x,y,a1,yy;
 10 }a[M];
 11 struct dat
 12 {
 13     int F,id;
 14 }b[M];
 15 int n,mo[M],zhan[M],tnt,sum[M],st=1,ans[M],N;
 16 bool mark[M];
 17 bool cmp(data b1,data b2)
 18 {
 19     return b1.a1<b2.a1;
 20 }
 21 bool cmp1(dat b1,dat b2)
 22 {
 23     return b1.F<b2.F;
 24 }
 25 void jia(int a1,int a2)
 26 {
 27     for(;a1<=N;a1+=a1&-a1)
 28       sum[a1]+=a2;
 29     return;
 30 }
 31 void mobiwus()
 32 {
 33     mo[1]=1;
 34     for(int i=2;i<=N;i++)
 35       {
 36         if(!mark[i])
 37           {
 38             zhan[++tnt]=i;
 39             mo[i]=-1;
 40           }
 41         for(int j=1;i*zhan[j]<=N&&j<=tnt;j++)
 42           {
 43             mark[i*zhan[j]]=1;
 44             if(i%zhan[j])
 45               mo[i*zhan[j]]=mo[i]*mo[zhan[j]];
 46             else
 47               mo[i*zhan[j]]=0;
 48           }
 49       }
 50     return;
 51 }
 52 int query(int a1)
 53 {
 54     int ss=0;
 55     for(;a1;a1-=a1&-a1)
 56       ss+=sum[a1];
 57     return ss;
 58 }
 59 void su(int n,int m,int j)
 60 {
 61     if(n>m)
 62       swap(n,m);
 63     int last=0,re=0;
 64     for(int i=1;i<=n;i=last+1)
 65       {
 66         last=min(n/(n/i),m/(m/i));
 67         re+=(n/i)*(m/i)*(query(last)-query(i-1));
 68       }
 69     ans[j]=re;
 70     return;
 71 }
 72 int main()
 73 {
 74     scanf("%d",&n);
 75     for(int i=1;i<=n;i++)
 76       {
 77         scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].a1);
 78         a[i].yy=i;
 79         N=max(N,a[i].x);
 80         N=max(N,a[i].y);
 81       }
 82     sort(a+1,a+n+1,cmp);
 83     mobiwus();
 84     for(int i=1;i<=N;i++)
 85       {
 86         b[i].F=1;
 87         b[i].id=i;
 88       }
 89     for(int i=2;i<=N;i++)
 90       for(int j=1;j*i<=N;j++)
 91         b[i*j].F+=i;
 92     sort(b+1,b+N+1,cmp1);
 93     for(int i=1;i<=n;i++)
 94       {
 95         for(;b[st].F<=a[i].a1&&st<=N;st++)
 96           for(int j=1;j*b[st].id<=N;j++)
 97              jia(j*b[st].id,b[st].F*mo[j]);       
 98         su(a[i].x,a[i].y,a[i].yy);
 99       }
100     for(int i=1;i<=n;i++)
101       printf("%d\n",ans[i]&0x7fffffff);
102     return 0;
103 }

莫比乌斯反演

你可能感兴趣的:(bzoj 3529: [Sdoi2014]数表)