zoukankan      html  css  js  c++  java
  • PGCD2

    这题肝了三四天,其他啥也没做...

    传送门

    然后...双倍经验

    简单版

    不知道为什么会脑抽去帮 LZ_101 大佬验题...

    题目和被 A 穿的 PGCD 一样,数据范围变成大概 2e11 ...

    于是我们就要考虑用更加优秀的做法去解决这道题了

    首先我们得想到 PGCD 中最优秀的解法:

    [ANS=sum_{i=1}^{n} lfloor {nover d} floor lfloor {mover d} floor sum_{p∈ prime ,p|d} mu({pover d}) ]

    这里我们令 (sum(d)=sum_{p∈ prime ,p|d} mu({pover d})) ,那么这个东西可以在线性筛中预处理出来,具体方法看代码中线性筛处理部分

    然后我们考虑数论分块时要能够 O(1) 得到这个 sum 的前缀和,那么我们发现这个函数不是积性函数(况且你能找到一个合适的 g 来和它卷积么),于是不能用杜教筛求解

    那么我们自然想到可以处理非积性函数的 min_25 筛了

    我们先 min_25 预处理出素数个数的前缀和

    然后第二部分中一遍处理 Mu 的信息,一遍处理 Sum ,也就是需要求的答案

    那么我们令 (Sum(n,j)) 表示 n 以内最小质因子大于等于 (p_j) 或是 质数的 sum 函数的前缀和,令 (Mu(n,j)) 表示 n 以内最小质因子大于等于 (p_j) 的 mu 函数的前缀和,然后转移就是:

    [Sum(n,j)=Sum(n,j+1)+Mu({nover p_j},j+1)-Sum({nover p_j},j+1)+2* j +({nover p_j^{~~ 2}}<=p_j~ ?~ Mu({nover p_j^{~~ 2}},j+1)+j ~:~ 0) ]

    [Mu(n,j)=Mu(n,j+1)+Mu({nover p_j},j+1)+j ]

    最后我们处理出来的所有 (Sum(n,1)) 就是数论分块里面要用到的 sum 的前缀和了

    学过 min_25 的人都知道为什么这样推导吧...

    code

    代码... 人傻常数大.jpg

    //by Judge
    #include<bits/stdc++.h>
    #include<unordered_map>
    #define Rg register
    #define fp(i,a,b) for(Rg int i=(a),I=(b)+1;i<I;++i)
    #define fd(i,a,b) for(Rg int i=(a),I=(b)-1;i>I;--i)
    #define III __int128
    #define ll long long
    using namespace std;
    const int M=1e7+3;
    typedef int arr[M];
    typedef ll ARR[M];
    #ifndef Judge
    #define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
    #endif
    char buf[1<<21],*p1=buf,*p2=buf;
    template<class T>inline T Min(T a,T b){return a<b?a:b;}
    template<class T>inline bool cmax(T& a,T b){return a<b?a=b,1:0;}
    inline ll read(){ ll x=0,f=1; char c=getchar();
    	for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
    	for(;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f;
    } char sr[1<<21],z[21];int CCF=-1,Z;
    inline void Ot(){fwrite(sr,1,CCF+1,stdout),CCF=-1;}
    inline void print(III x,char chr='
    '){
        if(CCF>1<<20)Ot();if(x<0)sr[++CCF]=45,x=-x;
        while(z[++Z]=x%10+48,x/=10);
        while(sr[++CCF]=z[Z],--Z);sr[++CCF]=chr;
    } ll n,m,MX,sq,cnt; III ans; arr v,p,id1,id2;
    ARR w,h,mu,sum,S; III Sum[M],Mu[M]; unordered_map<ll,III> ANS;
    inline void prep_sum(ll n){ mu[1]=1;
    	fp(i,2,n){ if(!v[i]) p[++cnt]=i,mu[i]=-1,sum[i]=1;
    		for(int j=1,k;j<=cnt&&p[j]*i<=n;++j){ v[k=i*p[j]]=1;
    			if(!(i%p[j])){ sum[k]=mu[i]; break; }
    			mu[k]=-mu[i],sum[k]=mu[i]-sum[i];
    		} S[i]=sum[i],sum[i]+=sum[i-1];
    	}
    }
    inline int ID(Rg ll x){return x<=sq?id1[x]:id2[n/x];}
    inline void prep_num(ll N){ if(N<=MX) return ;
    	sq=sqrt(n=N),m=0; int tot=upper_bound(p+1,p+1+cnt,sq)-p-1;
    	for(Rg ll l=1;l<=n;l=w[m]+1) w[++m]=n/(n/l),h[m]=w[m]-1,w[m]<=sq?id1[w[m]]=m:id2[n/w[m]]=m;
    	fp(j,1,tot) for(Rg int i=m;i&&1ll*p[j]*p[j]<=w[i];--i) h[i]-=h[ID(w[i]/p[j])]-j+1;
    	fp(i,1,m) Mu[i]=-h[i],Sum[i]=h[i];
    	fd(j,tot,1) for(Rg int i=m,k,kk;i&&1ll*p[j]*p[j]<=w[i];--i) k=ID(w[i]/p[j]),kk=ID(w[k]/p[j]),
    		Sum[i]+=Mu[k]-Sum[k]+(j<<1)-(w[kk]>=p[j]?Mu[kk]+j:0)-1,Mu[i]-=Mu[k]+j;
    	fp(i,1,m) ANS[w[i]]=Sum[i];
    }
    inline III GET(Rg ll n){ return n<=MX?sum[n]:ANS[n];}
    #define swap(x,y) (x)^=(y)^=(x)^=(y)
    int main(){ int T=read(); prep_sum(MX=1e7);
    	fp(i,1,T){ Rg ll n=read(),m=read(),bl;
    		if(n>m) swap(n,m); ans=0,ANS.clear(),prep_num(n),prep_num(m);
    		for(Rg ll l=1,r;l<=n;l=r+1) r=Min(n/(n/l),m/(m/l)),
    			ans+=(GET(r)-GET(l-1))*(n/l)*(m/l); print(ans);
    	} return Ot(),0;
    }
    
  • 相关阅读:
    An Introduction to the Linuxbased Assignments
    [读书笔记]Binary Hancks(1)
    haneWIN NFS Server
    [读书笔记]Binary Hancks(2) livepatch在X86下的实践
    CTNG编译错误以及解决办法
    [转]ucLinux下sqlite数据库移植全攻略
    程序员该有的艺术气质—SOLID原则
    Httpclient远程调用WebService示例(Eclipse+httpclient)
    四种生成和解析XML文档的方法详解(介绍+优缺点比较+示例)
    全网首发:原创SQL数据库同步工具
  • 原文地址:https://www.cnblogs.com/Judge/p/10695339.html
Copyright © 2011-2022 走看看