zoukankan      html  css  js  c++  java
  • luogu P4619 [SDOI2018]旧试题

    luogu

    先考虑(d(i,j,k))是啥,首先会有(d(i,j)=sum_{x|i}sum_{y|j}[gcd(x,y)=1]),可以推广得到(d(i,j,k)=sum_{x|i}sum_{y|j}sum_{z|k}[gcd(x,y)=1][gcd(y,z)=1][gcd(x,z)=1]),然后开始化式子

    (sum_{i=1}^{A}sum_{j=1}^{B}sum_{k=1}^{C}sum_{x|i}sum_{y|j}sum_{z|k}[gcd(x,y)=1][gcd(y,z)=1][gcd(x,z)=1])

    (sum_{i=1}^{A}sum_{j=1}^{B}sum_{k=1}^{C}sum_{x|i}sum_{y|j}sum_{z|k}sum_{a|x,a|y}mu(a)sum_{b|y,b|z}mu(b)sum_{c|z,c|x}mu(c))

    (sum_{a=1}^{min(A,B)}sum_{b=1}^{min(B,C)}sum_{c=1}^{min(C,A)}mu(a)mu(b)mu(c)sum_{mathrm{lcm}(c,a)|x}sum_{mathrm{lcm}(a,b)|y}sum_{mathrm{lcm}(b,c)|z}lfloorfrac{A}{x} floorlfloorfrac{B}{y} floorlfloorfrac{C}{z} floor)

    这里记(F_A(x)=sum_{x|i}lfloorfrac{A}{i} floor),(F_B(x),F_C(x))同理,可得

    (sum_{a=1}^{min(A,B)}sum_{b=1}^{min(B,C)}sum_{c=1}^{min(C,A)}mu(a)mu(b)mu(c)F_A(mathrm{lcm}(c,a))F_B(mathrm{lcm}(a,b))F_C(mathrm{lcm}(b,c)))

    到这个时候就可以讨论了,首先是(a=b=c)的情况,可以做到(O(n))统计;然后是(abc)中两个相等且另外一个不相等,以及三个都不相等的情况.答案的这个形式就是枚举三个不同的数,然后考虑他们两两之间的贡献,可以联想到建图,连上所有的((a,b,mathrm{lcm}(a,b)))即可套三元环计数.然后我们显然只用考虑(mu(a) eq 0,mu(b) eq 0,mathrm{lcm}(a,b)le max{A,B,C})的边,可以发现这样的边只有约(8*10^5)条,所以如果是(abc)中两个相等且和另外一个不相等的情况,就是一次枚举每条边,然后枚举这条边会对应的(aab,abb,aac,acc,bbc,bcc)六种情况;如果是(abc)都不相等,那么对应到图上就是枚举一个三元环,所以使用三元环计数即可,枚举三元环复杂度(O(|E|^{1.5})),再讨论这三个点分别(abc)中的哪个来统计答案

    然后这题较卡常,首先(F_A,F_B,F_C)可以(O(nlogn))预处理;然后是建图问题,因为(mathrm{lcm}(a,b)=gcd(a,b)frac{a}{gcd(a,b)}frac{b}{gcd(a,b)}),那么只要枚举(gcd(a,b)frac{a}{gcd(a,b)}frac{b}{gcd(a,b)})并且保证他们的乘积(le max{A,B,C}),可以发现这个复杂度类似调和极数,为(O(nlog^2n));还有就是能并在一起计算的式子最好并在一起

    #include<bits/stdc++.h>
    #define LL long long
    #define uLL unsigned long long
    
    using namespace std;
    const int N=1e5+10,M=N*10,mod=1e9+7;
    int rd()
    {
        int x=0,w=1;char ch=0;
        while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+(ch^48);ch=getchar();}
        return x*w;
    }
    /*int to[M],nt[M],w[M],hd[N],tot=1;
    void adde(int x,int y,int z){++tot,to[tot]=y,nt[tot]=hd[x],w[tot]=z,hd[x]=tot;}*/
    void ad(int &x,int y){x+=y,x-=x>=mod?mod:0;}
    int gcd(int a,int b){return b?gcd(b,a%b):a;}
    int prm[N],pp[N],f[N],g[N],h[N],mu[N],tt,nm[N],tn,id[N],dg[N],vs[N],te;
    int n,a,b,c,ans;
    void inii(int *f,int nn)
    {
        memset(f,0,sizeof(int)*(n+1));
        for(int i=1;i<=nn;++i)
    	for(int j=1;i*j<=nn;++j)
    	    ad(f[i],nn/(i*j));
    }
    struct node{int x,y,z;}ee[M];
    vector<node> gg[N];
    vector<node>::iterator i1,i2;
    
    int main()
    {
    ///wdnmd
        mu[1]=1;
        for(int i=2;i<=N-5;++i)
        {
        	if(!pp[i]) pp[i]=1,prm[++tt]=i,mu[i]=-1;
        	for(int j=1;i*prm[j]<=N-5;++j)
        	{
        	    if(i%prm[j]==0){pp[i*prm[j]]=pp[i]+1;break;}
        	    pp[i*prm[j]]=1,mu[i*prm[j]]=-mu[i];
        	}
        }
        for(int i=1;i<=N-5;++i)
    	if(mu[i]) nm[++tn]=i,id[i]=tn;
        int lt=tn,T=rd();
        while(T--)
        {
        	a=rd(),b=rd(),c=rd();
        	n=max(max(a,b),c);
        	inii(f,a),inii(g,b),inii(h,c);
        	tn=lt;
        	while(nm[tn]>n) --tn;
        	te=0;
        	memset(dg,0,sizeof(int)*(n+1))/*,memset(hd,0,sizeof(int)*(n+1)),tot=1*/;
        	for(int d=1;d<=n;++d)
        	    for(int i=1;1ll*i*d<=n;++i)
        	    	for(int j=i+1;1ll*i*j*d<=n;++j)
        	    	    if(mu[i*d]&&mu[j*d]&&gcd(i,j)==1) ++dg[id[i*d]],++dg[id[j*d]],ee[++te]=(node){id[i*d],id[j*d],i*j*d};
        	for(int i=1;i<=tn;++i) gg[i].clear();
        	for(int i=1;i<=te;++i)
        	{
        	    int x=ee[i].x,y=ee[i].y,z=ee[i].z;
        	    if(dg[x]>dg[y]) swap(x,y);
        	    gg[x].push_back((node){i,y,z});
        	}
        	ans=0;
        	for(int x=1;x<=tn;++x)
        	{
        	    for(i1=gg[x].begin();i1!=gg[x].end();++i1)
        	    {
            		int i=(*i1).x,y=(*i1).y,xx=nm[x],yy=nm[y],w=(*i1).z;
            		vs[y]=i;
            		int nw=(1ll*f[xx]*g[w]%mod*h[w]+1ll*f[w]*g[xx]%mod*h[w]+1ll*f[w]*g[w]%mod*h[xx])%mod;
            		ad(ans,(~(mu[xx]*mu[xx]*mu[yy])?nw:mod-nw));
            		nw=(1ll*f[yy]*g[w]%mod*h[w]+1ll*f[w]*g[yy]%mod*h[w]+1ll*f[w]*g[w]%mod*h[yy])%mod;
            		ad(ans,(~(mu[xx]*mu[yy]*mu[yy])?nw:mod-nw));
        	    }
        	    for(i1=gg[x].begin();i1!=gg[x].end();++i1)
        	    {
            		int i=(*i1).x,y=(*i1).y;
            		for(i2=gg[y].begin();i2!=gg[y].end();++i2)
            		{
            		    int j=(*i2).x,z=(*i2).y;
            		    if(vs[z])
            		    {
                			int k=vs[z],w1=ee[i].z,w2=ee[j].z,w3=ee[k].z;
                			int nw=(1ll*f[w1]*g[w2]%mod*h[w3]+1ll*f[w1]*g[w3]%mod*h[w2]+1ll*f[w2]*g[w1]%mod*h[w3]+1ll*f[w2]*g[w3]%mod*h[w1]+1ll*f[w3]*g[w1]%mod*h[w2]+1ll*f[w3]*g[w2]%mod*h[w1])%mod;
                			ad(ans,(~(mu[nm[x]]*mu[nm[y]]*mu[nm[z]])?nw:mod-nw));
            		    }
            		}
                }
            	for(i1=gg[x].begin();i1!=gg[x].end();++i1) vs[(*i1).y]=0;
        	}
        	for(int i=1;i<=tn;++i)
        	{
        	    int nw=1ll*f[nm[i]]*g[nm[i]]%mod*h[nm[i]]%mod;
        	    ad(ans,(~(mu[nm[i]]*mu[nm[i]]*mu[nm[i]])?nw:mod-nw));
        	}
        	printf("%d
    ",ans);
        }
        return 0;
    }
    
  • 相关阅读:
    poj 3666 Making the Grade
    poj 3186 Treats for the Cows (区间dp)
    hdu 1074 Doing Homework(状压)
    CodeForces 489C Given Length and Sum of Digits...
    CodeForces 163A Substring and Subsequence
    CodeForces 366C Dima and Salad
    CodeForces 180C Letter
    CodeForces
    hdu 2859 Phalanx
    socket接收大数据流
  • 原文地址:https://www.cnblogs.com/smyjr/p/12373372.html
Copyright © 2011-2022 走看看