zoukankan      html  css  js  c++  java
  • [bzoj3529]数表

    记f(n)表示n的约数和,先不考虑a的限制,那么即求$sum_{i=1}^{n}sum_{j=1}^{m}f(gcd(i,j))$
    枚举$d=gcd(i,j)$,即$sum_{d=1}^{n}f(d)sum_{g|d}(n/gd)(m/gd)mu(g)$(后面就是指公约数为d的数对个数)
    令$t=gd$,即$sum_{t=1}^{n}(n/t)(m/t)sum_{d|t}f(d)cdot mu(t/d)$,对后半部分预处理(先线性筛出f和$mu$,然后$o(nln(n))$求)+前半部分数论分块即可快速求出
    离线,将询问按照a排序,然后不断插入f(i)(即修改所有是i约数的t位置,暴力),用树状数组来支持数论分块即可

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 100005
     4 #define L (k<<1)
     5 #define R (L+1)
     6 #define mid (l+r>>1)
     7 #define ui unsigned int
     8 struct ji{
     9     int n,m,a,id;
    10     bool operator < (const ji &k)const{
    11         return a<k.a;
    12     }
    13 }q[N];
    14 int t,n,m,a,vis[N],p[N],mu[N],id[N];
    15 ui f[N],ans[N],tr[N<<2];
    16 bool cmp(int x,int y){
    17     return f[x]<f[y];
    18 }
    19 void update(int k,int l,int r,int x,int y){
    20     if (l==r){
    21         tr[k]+=y;
    22         return;
    23     }
    24     if (x<=mid)update(L,l,mid,x,y);
    25     else update(R,mid+1,r,x,y);
    26     tr[k]=tr[L]+tr[R];
    27 }
    28 ui query(int k,int l,int r,int x,int y){
    29     if ((l>y)||(x>r))return 0;
    30     if ((x<=l)&&(r<=y))return tr[k];
    31     return query(L,l,mid,x,y)+query(R,mid+1,r,x,y);
    32 }
    33 int main(){
    34     mu[1]=f[1]=1;
    35     for(int i=2;i<N-4;i++){
    36         if (!vis[i]){
    37             p[++p[0]]=i;
    38             mu[i]=-1;
    39             f[i]=i+1;
    40         }
    41         for(int j=1;(j<=p[0])&&(i*p[j]<N-4);j++){
    42             vis[i*p[j]]=1;
    43             for(int k=i;;k/=p[j])
    44                 if (k%p[j]){
    45                     if (k>1)f[i*p[j]]=f[k]*f[i*p[j]/k];
    46                     else f[i*p[j]]=f[i]+i*p[j];
    47                     break;
    48                 }
    49             if (i%p[j]==0)break;
    50             mu[i*p[j]]=-mu[i];
    51         }
    52     }
    53     for(int i=1;i<N-4;i++)id[i]=i;
    54     sort(id+1,id+N-4,cmp);
    55     scanf("%d",&t);
    56     for(int i=1;i<=t;i++){
    57         scanf("%d%d%d",&n,&m,&a);
    58         if (n>m)swap(n,m); 
    59         q[i]=ji{n,m,a,i};
    60     }
    61     sort(q+1,q+t+1);
    62     for(int i=1,j=1;i<=t;i++){
    63         for(;(j<N-4)&&(f[id[j]]<=q[i].a);j++)
    64             for(int k=1;k<=(N-5)/id[j];k++)update(1,1,N-5,k*id[j],f[id[j]]*mu[k]);
    65         for(int l=1,r;l<=q[i].n;l=r+1){
    66             r=min(q[i].n/(q[i].n/l),q[i].m/(q[i].m/l));
    67             ans[q[i].id]+=(q[i].n/l)*(q[i].m/l)*query(1,1,N-5,l,r);
    68         }
    69     }
    70     for(int i=1;i<=t;i++)printf("%u
    ",ans[i]&2147483647);
    71 }
    View Code
  • 相关阅读:
    get pc name in LAN
    study spring
    android install
    【转】Java:Session详解
    classic problem: producer and consumer
    tomcat install
    验证Monitor.PulseAll功效
    (转)Windows7的图形架构与DX的那点事
    Cannot open your default email folders. The attempt to log on to Microsoft Exchange has failed.
    Monitor.Wait初探(8)
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/11733868.html
Copyright © 2011-2022 走看看