zoukankan      html  css  js  c++  java
  • [WC2014]时空穿梭

    声明:我还没有退役,只是Typora太好用,懒得写博客了而已,比较好的题还是会放上来

    鼓起勇气写了一个冬令营

    有了[BZOJ3518] 点组计数的基础

    显然答案为

    [sum_{x_1=1}^{m_1}sum_{x_2=1}^{m_2}...sum_{x_n=1}^{m_n}(^{gcd(x_1,...x_n)-1}_{c-2})*prod_{i=1}^{n}(m_i-x_i) ]

    然而这次(gcd)函数在组合数里面

    并不能用(varphi)反演

    所以这次用(mu)反演

    [sum_{x_1=1}^{m_1}sum_{x_2=1}^{m_2}...sum_{x_n=1}^{m_n}(^{gcd(x_1,...x_n)-1}_{c-2})*prod_{i=1}^{n}{(m_i-x_i)} \=sum_{d=1}^{m}{(^{d-1}_{c-2})}sum_{x_1=1}^{lfloor frac{m_1}{d} floor}sum_{x_2=1}^{lfloor frac{m_2}{d} floor}...sum_{x_n=1}^{lfloor frac{m_n}{d} floor}{[gcd(x_1,...x_n)=1]*prod_{i=1}^{n}{(m_i-d*x_i)}} \=sum_{d=1}^{m}{(^{d-1}_{c-2})}sum_{x_1=1}^{lfloor frac{m_1}{d} floor}sum_{x_2=1}^{lfloor frac{m_2}{d} floor}...sum_{x_n=1}^{lfloor frac{m_n}{d} floor}{sum_{t|gcd(x_1,...x_n)}{mu(t)}prod_{i=1}^{n}{(m_i-d*x_i)}} \=sum_{d=1}^{m}{(^{d-1}_{c-2})}sum_{t=1}^{lfloor frac{m}{d} floor}{mu(t)}sum_{x_1=1}^{lfloor frac{m_1}{dt} floor}sum_{x_2=1}^{lfloor frac{m_2}{dt} floor}...sum_{x_n=1}^{lfloor frac{m_n}{dt} floor}prod_{i=1}^{n}{(m_i-d*t*x_i)} \=sum_{d=1}^{m}{(^{d-1}_{c-2})}sum_{t=1}^{lfloor frac{m}{d} floor}{mu(t)}sum_{x_1=1}^{lfloor frac{m_1}{dt} floor}{{(m_1-d*t*x_1)}}sum_{x_2=1}^{lfloor frac{m_2}{dt} floor}{(m_2-d*t*x_2)}...sum_{x_n=1}^{lfloor frac{m_n}{dt} floor}{(m_n-d*t*x_n)} \=sum_{d=1}^{m}{(^{d-1}_{c-2})}sum_{t=1}^{lfloor frac{m}{d} floor}{mu(t)}prod_{i=1}^{n}{(m_i*lfloor frac{m_i}{dt} floor-d*t*frac{lfloor frac{m_1}{dt} floor*(lfloor frac{m_1}{dt} floor+1)}{2})} \=sum_{d=1}^{m}sum_{d'|d}{(^{d'-1}_{c-2})*mu(frac{d}{d'})*prod_{i=1}^{n}{(m_i*lfloor frac{m_i}{d} floor-d*frac{lfloor frac{m_1}{d} floor*(lfloor frac{m_1}{d} floor+1)}{2})}} ]

    至此

    复杂度为(O(Tmn))算下来大概(1e8)

    然而还可以再优化

    [F(d)=prod_{i=1}^{n}{(m_i*lfloorfrac{m_i}{d} floor-d*frac{lfloorfrac{m_1}{d} floor*(lfloor frac{m_1}{d} floor+1)}{2})} ]

    显然(F(d))是关于(d)的一个(n)次函数

    可以(O(n^2))计算其所有系数

    设这些系数是(a_0,a_1,...a_n)

    原式即可变为

    [sum_{d=1}^{m}sum_{d'|d}{(^{d'-1}_{c-2})*mu(frac{d}{d'})*sum_{i=0}^{n}{a_i*d^i}} \=sum_{d=1}^{m}sum_{i=0}^{n}{a_i*(d^i*sum_{d'|d}{(^{d'-1}_{c-2})*mu(frac{d}{d'}}))} ]

    后面那部分可以在(O(mnc))内预处理出前缀和

    每次询问(O(n^3sqrt{m}))(处理(a)(n^2),需要算(nsqrt{m})次,因为(d)(nsqrt{m})种取值)

    代码如下

    #include<bits/stdc++.h>
    
    using namespace std;
    
    #define gc c=getchar()
    #define r(x) read(x)
    #define ll long long 
    
    template<typename T>
    inline void read(T&x){
        x=0;T k=1;char gc;
        while(!isdigit(c)){if(c=='-')k=-1;gc;}
        while(isdigit(c)){x=x*10+c-'0';gc;}x*=k;
    }
    
    const int p=10007;
    const int N=1e5+7;
    const int S=21;
    const int W=12;
    
    inline int add(int a,int b){
    	a+=b;
    	if(a>=p)a-=p;
    	return a;
    }
    
    int C[N][S],P[N][W],f[N][S],sum[N][S][W];
    
    int tot;
    int pri[N],mu[N];
    bool mark[N];
    
    inline void pre(int n){
    	mu[1]=1;
    	for(int i=2;i<=n;++i){
    		if(!mark[i])pri[++tot]=i,mu[i]=-1;
    		for(int j=1,tmp;j<=tot&&(tmp=i*pri[j])<=n;++j){
    			mark[tmp]=1;
    			if(i%pri[j]==0){
    				mu[tmp]=0;
    				break;
    			}
    			mu[tmp]=-mu[i];
    		}
    	}
    	C[0][0]=1;
    	for(int i=1;i<=n;++i){
    		C[i][0]=1;
    		for(int j=1;j<S;++j){
    			C[i][j]=add(C[i-1][j-1],C[i-1][j]);
    		}
    	}
    	for(int i=0;i<=n;++i){
    		P[i][0]=1;
    		for(int j=1;j<W;++j){
    			P[i][j]=P[i][j-1]*i%p;
    		}
    	}
    	for(int i=1;i<=n;++i){
    		for(int j=1;i*j<=n;++j){
    			for(int k=2;k<S;++k){
    				f[i*j][k]=add(f[i*j][k],add(p,C[i-1][k-2]*mu[j]));
    			}
    		}
    	}
    	for(int i=1;i<=n;++i){
    		for(int j=2;j<S;++j){
    			for(int k=0;k<W;++k){
    				sum[i][j][k]=add(sum[i][j][k],add(sum[i-1][j][k],f[i][j]*P[i][k]%p));
    			}
    		}
    	}
    }
    
    int a[W];
    
    struct query{
    	int n,c,M;
    	int m[W];
    
    	inline void init(int d){
    		memset(a,0,sizeof(a));
    		a[0]=1;
    		for(int i=1;i<=n;++i){
    			ll t=m[i]/d;
    			ll x=m[i]*t%p;
    			ll y=p-(t*(t+1)>>1)%p;
    			for(int j=n;j;--j){
    				a[j]=(a[j]*x+a[j-1]*y)%p;
    			}
    			a[0]=a[0]*x%p;
    		}
    	}
    
    	inline void solve(){
    		ll ans=0;
    		for(int i=1,nex;i<=M;i=nex+1){
    			nex=M;
    			for(int j=1;j<=n;++j){
    				nex=min(nex,m[j]/(m[j]/i));
    			}
    			init(i);
    			for(int j=0;j<=n;++j){
    				ans+=a[j]*add(sum[nex][c][j],p-sum[i-1][c][j]);
    			}
    		}
    		printf("%lld
    ",ans%p);
    	}
    
    }Q[1005];
    
    int main(){
    //	freopen(".in","r",stdin);
    //	freopen(".out","w",stdout);
    	int T,MaxM=0;r(T);
    	for(int i=1;i<=T;++i){
    		r(Q[i].n),r(Q[i].c);Q[i].M=N;
    		for(int j=1;j<=Q[i].n;++j){
    			r(Q[i].m[j]);
    			MaxM=max(MaxM,Q[i].m[j]);
    			Q[i].M=min(Q[i].M,Q[i].m[j]);
    		}
    	}
    	pre(MaxM);
    	for(int i=1;i<=T;++i)Q[i].solve();
    	return 0;
    }
    
    
  • 相关阅读:
    storyboard文件的认识
    设置程序启动时加载的storyboard
    IBAction和IBOutlet
    listview
    JDK下载地址
    [置顶] Docker学习总结(2)——Docker实战之入门以及Dockerfile(二)
    [置顶] Docker学习总结(1)——Docker实战之入门以及Dockerfile(一)
    [置顶] Docker学习总结(1)——Docker实战之入门以及Dockerfile(一)
    XML学习总结(2)——XML简单介绍
    XML学习总结(2)——XML简单介绍
  • 原文地址:https://www.cnblogs.com/yicongli/p/10165489.html
Copyright © 2011-2022 走看看