zoukankan      html  css  js  c++  java
  • 洛谷P3455 [POI2007]ZAP-Queries(莫比乌斯反演)

    传送门

    设$$f(k)=sum_{i=1}^{a}sum_{j=1}^{b}[gcd(i,j)=k]$$

    $$g(n)=sum_{n|k}f(k)=lfloorfrac{a}{n} floorlfloorfrac{b}{n} floor$$

    根据莫比乌斯反演定理可以推出$$f(n)=sum_{n|k}mu(lfloorfrac{k}{n} floor)g(k)$$

    那么可以发现$ans=f(d)$

    然后用推出来的结论带进去

    $$ans=sum_{d|k}mu(lfloorfrac{k}{d} floor)g(k)$$

    枚举$lfloorfrac{k}{d} floor$设为$t$

    $$ans=sum_{t=1}^{min(lfloorfrac{a}{d} floor,lfloorfrac{b}{d} floor)}mu(t)lfloorfrac{a}{td} floorlfloorfrac{b}{td} floor$$

    对于$lfloorfrac{a}{td} floorlfloorfrac{b}{td} floor$相同的一段我们可以直接用前缀和算出答案

    总而言之就是先预处理出$mu$的前缀和然后用整除分块,那么每一次询问的复杂度就是$O(sqrt{n})$

     1 //minamoto
     2 #include<cstdio>
     3 #include<iostream>
     4 #define ll long long
     5 using namespace std;
     6 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
     7 char buf[1<<21],*p1=buf,*p2=buf;
     8 inline int read(){
     9     #define num ch-'0'
    10     char ch;bool flag=0;int res;
    11     while(!isdigit(ch=getc()))
    12     (ch=='-')&&(flag=true);
    13     for(res=num;isdigit(ch=getc());res=res*10+num);
    14     (flag)&&(res=-res);
    15     #undef num
    16     return res;
    17 }
    18 const int N=6e5+5;
    19 int p[N],mu[N],vis[N],m,sum[N];ll ans,lim;
    20 void init(int n){
    21     mu[1]=1;
    22     for(int i=2;i<=n;++i){
    23         if(!vis[i]) mu[i]=-1,p[++m]=i;
    24         for(int j=1;j<=m&&p[j]*i<=n;++j){
    25             vis[i*p[j]]=1;
    26             if(i%p[j]==0) break;
    27             mu[i*p[j]]=-mu[i];
    28         }
    29     }
    30     for(int i=1;i<=n;++i) sum[i]=sum[i-1]+mu[i];
    31 }
    32 int main(){
    33 //    freopen("testdata.in","r",stdin);
    34     int n,m,T,d;scanf("%d",&T);
    35     init(50000);
    36     while(T--){
    37         scanf("%d%d%d",&n,&m,&d);ans=0;
    38         lim=min(n/d,m/d);
    39         
    40         for(int l=1,r;l<=lim;l=r+1){
    41             r=min(n/(n/l),m/(m/l));
    42             ans+=1ll*(n/(l*d))*(m/(l*d))*(sum[r]-sum[l-1]);
    43         }
    44         printf("%lld
    ",ans);
    45     }
    46     return 0;
    47 }
  • 相关阅读:
    Spring spEL
    Spring 使用外部部署文件
    Spring 自动装配
    spring 属性配置细节
    hdu 1054 Strategic Game
    fzu 2037 Maximum Value Problem
    将博客搬至CSDN
    HDU 4714 Tree2Cycle
    HDU 1009 The Shortest Path in Nya Graph
    POJ 1942 Paths on a Grid 组合数的优化
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/9688653.html
Copyright © 2011-2022 走看看