• 【BZOJ 3529】 [Sdoi2014]数表 (莫比乌斯+分块+离线+树状数组)


    3529: [Sdoi2014]数表

    Description

        有一张N×m的数表,其第i行第j列(1 < =i < =礼,1 < =j < =m)的数值为
    能同时整除i和j的所有自然数之和。给定a,计算数表中不大于a的数之和。

    Input

        输入包含多组数据。
        输入的第一行一个整数Q表示测试点内的数据组数,接下来Q行,每行三个整数n,m,a(|a| < =10^9)描述一组数据。

    Output

        对每组数据,输出一行一个整数,表示答案模2^31的值。

    Sample Input

    2
    4 4 3
    10 10 5

    Sample Output

    20
    148
     
     
    【分析】
      
      先假设没有a的限制。。
      设g(i)=ΣΣ[(x,y)==i](1<=x<=n,1<==y<=m)
         g(i)=Σmu[d]*(n/(i*d))*(m/(i*d))
         尝试把i和d分开,设D=i*d
      那么g(i)=(n/D)*(M/D)*Σmu[i/D]  (i|D)
      设f(i)为i的约数和,这个可以nlogn求出来,那么ans=g(i)*f(i)=(n/D)*(M/D)*Σmu[i/D]*f(i) (i|D)
     
      对于a的限制,是说f(i)<=a的东西对ans有贡献,其他的没有贡献。
      所以就离线一下~~按照f(i)排序,询问按照a排序,因为要询问前缀和,所以当他开始有贡献的时候就把他放到树状数组里面去。
      剩下的就是分块处理了。
     
      Mod的地要自然溢出最后取模?不然会超时,像我一样~
     
     
      别人的题解:

     
     
    代码如下:
      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<algorithm>
      6 #include<queue>
      7 #include<cmath>
      8 using namespace std;
      9 #define Maxn 100010
     10 #define LL unsigned int
     11 #define INF 0xfffffff
     12 LL mx;
     13 LL Mod;
     14 
     15 int mu[Maxn];
     16 LL pri[Maxn],pl;
     17 bool q[Maxn];
     18 
     19 
     20 struct node
     21 {
     22     LL x,y,a,ans,id;
     23 }t[Maxn],f[Maxn];
     24 
     25 LL mymin(LL x,LL y) {return x<y?x:y;}
     26 LL mymax(LL x,LL y) {return x>y?x:y;}
     27 
     28 bool cmp(node x,node y) {return x.a<y.a;}
     29 bool cmp2(node x,node y) {return x.id<y.id;}
     30 
     31 void get_mu()
     32 {
     33     pl=0;
     34     memset(q,1,sizeof(q));
     35     mu[1]=1;
     36     for(LL i=2;i<=mx;i++)
     37     {
     38         if(q[i])
     39         {
     40             pri[++pl]=i;
     41             mu[i]=-1;
     42         }
     43         for(LL j=1;j<=pl;j++)
     44         {
     45             if(i*pri[j]>mx) break;
     46             q[i*pri[j]]=0;
     47             if(i%pri[j]==0) mu[i*pri[j]]=0;
     48             else mu[i*pri[j]]=-mu[i];
     49             if(i%pri[j]==0) break;
     50         }
     51     }
     52     for(LL i=1;i<=mx;i++) f[i].a=0;
     53     for(LL i=1;i<=mx;i++)
     54      for(LL j=i;j<=mx;j+=i)
     55         f[j].a=f[j].a+i;
     56     for(LL i=1;i<=mx;i++) f[i].id=i;
     57 }
     58 
     59 LL c[Maxn],as[Maxn];
     60 
     61 LL add(LL x,LL y)
     62 {
     63     as[x]+=y;
     64     for(LL i=x;i<=mx;i+=i&(-i))
     65         c[i]+=y;
     66 }
     67 
     68 LL get_sum(LL x)
     69 {
     70     LL ans=0;
     71     for(LL i=x;i>=1;i-=i&(-i))
     72       ans+=c[i];
     73     return ans;
     74 }
     75 
     76 void change(LL x)
     77 {
     78     LL now=f[x].id;
     79     for(LL i=now;i<=mx;i+=now)
     80       add(i,(LL)(mu[i/now]*f[x].a));
     81 }
     82 
     83 
     84 LL get_ans(LL n,LL m)
     85 {
     86     LL ans=0,t;
     87     if(n>m) t=n,n=m,m=t;
     88     
     89     LL sq=(LL)ceil(sqrt((double)m));
     90     for(LL i=1;i<=mymin(sq,n);i++)
     91     {
     92         LL x=(LL)(n/i),y=(LL)(m/i);
     93         ans+=as[i]*(n/i)*(m/i);
     94     }
     95     
     96     
     97     for(LL i=sq+1;i<=n;)
     98     {
     99         LL x=n/i,y=m/i;
    100         LL r1=n/x+1,r2=m/y+1;
    101         if(r1>n+1) r1=n+1;
    102         if(r2>n+1) r2=n+1;
    103         LL r=mymin(r1,r2);
    104         
    105         ans+=(get_sum(r-1)-get_sum(i-1))*x*y;
    106         i=r;
    107     }
    108     
    109     return ans;
    110 }
    111 
    112 int main()
    113 {
    114     Mod=1;
    115     for(LL i=1;i<=31;i++) Mod*=2;
    116     
    117     LL T;
    118     T=1;
    119     scanf("%d",&T);
    120     
    121     mx=0;
    122     
    123     for(LL i=1;i<=T;i++)
    124     {
    125         scanf("%d%d%d",&t[i].x,&t[i].y,&t[i].a);
    126         mx=mymax(mx,mymin(t[i].x,t[i].y));
    127         t[i].id=i;
    128     }
    129     sort(t+1,t+1+T,cmp);
    130     get_mu();
    131     sort(f+1,f+1+mx,cmp);
    132     
    133     memset(c,0,sizeof(c));
    134     memset(as,0,sizeof(as));
    135     LL now=1;
    136     for(LL i=1;i<=T;i++)
    137     {
    138         while(f[now].a<=t[i].a&&now<=mx) change(now),now++;
    139         t[i].ans=get_ans(t[i].x,t[i].y);
    140     }
    141     sort(t+1,t+1+T,cmp2);
    142     
    143     for(LL i=1;i<=T;i++)
    144     {
    145         printf("%d
    ",(t[i].ans%Mod+Mod)%Mod);
    146     }
    147     return 0;
    148 }
    [BZOJ 3529]

    2016-09-03 10:57:57

     
  • 相关阅读:
    Spring(001)-Hello Spring
    actuator beans不展示
    Java读取property文件
    PostgreSQL 后端存储
    python 中global() 函数
    python项目配置文件格式
    大数据时代,数据成了研究的基石
    10w数据重建索引报错:java.lang.IllegalStateException: Batch statement cannot contain more than 65535 statements
    java学习day15--API-ArrayList--LinkedList
    java学习day14--API-集合(Collection)+List
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/5836471.html
Copyright © 2020-2023  润新知