zoukankan      html  css  js  c++  java
  • [BZOJ3202][SDOI2013]项链

    bzoj
    luogu

    sol

    数论多合一。
    可以考虑分两步做。
    1、求有多少种不同的珠子,设其数量为(m)
    2、用(m)种颜色对(n)个珠子的项链染色,要求相邻不同色,且旋转相同视作同一种方案,求方案数。

    求有多少种不同的珠子

    (A=sum_{i=1}^asum_{j=1}^asum_{k=1}^a[gcd(i,j,k)=1])
    然而算重了。
    如果(i,j,k)都不相等的话就多算了(6)次,如果有两个相等就多算了(3)次,如果三个都相等......那肯定是三个(1)啦,并没有多算。
    这个问题怎么解决呢?我们再算(B=sum_{i=1}^asum_{j=1}^a[gcd(i,j)=1]),那么答案就是(frac 16(A+3B+2))(把每种情况补齐到(6)次,再一起除以(6))。
    (A)(B)是很简单的莫比乌斯反演,具体来说就是:

    [A=sum_{i=1}^alfloorfrac ai floor^3mu(i)\B=sum_{i=1}^alfloorfrac ai floor^2mu(i) ]

    求染色方案

    这里要用到(Burnside)定理。
    这里的置换只有一种,就是旋转。设旋转(i)个位置,那么就会有产生(gcd(i,n))个等价类。
    所以答案就是$$frac{sum_{i=1}^nf_{gcd(i,n)}}{n}$$其中(f_i)表示(i)个点的环染色的方案数。也可以认为是给一个长为(n)的序列染色,然后保证首尾不同色的方案数。
    考虑对上式做一些简化。因为(gcd(i,n))一定是(n)的约数,所以可以枚举某个约数(d),然后答案就变成了$$frac{sum_{d|n}f_dsum_{i=1}^n[gcd(i,n)=d]}{n}=frac{sum_{d|n}f_dvarphi(frac nd)}{n}$$

    (f_n)

    考虑一下(f_n)的递推。

    [f_n=(m-2)f_{n-1}+(m-1)f_{n-2},f_1=0,f_2=m(m-1) ]

    讲道理的话,前一种转移表示在末尾填一个与首尾都不相同的颜色,这样有(m-2)种选择;后一种转移表示先填一个和首位相同的颜色,再填一个不同色,这样有(1 imes(m-1))种选择。
    然后就可以矩乘了。

    (f_n)的通项公式

    有人跟我讲这题要求通项公式我就没去写矩乘。常数优秀一点说不定跑得过?
    下面讲一下求通项公式

    [f_n-(m-2)f_{n-1}-(m-1)f_{n-2}=0 ]

    其特征方程$$x^2-(m-2)x-(m-1)=0$$
    解得其特征根$$x_1=-1,x_2=m-1$$
    于是设其通项公式为$$f_i=a(-1)^i+b(m-1)^i$$
    (f_1=0,f_2=m(m-1))代入解得$$a=1-m,b=1$$
    所以$$f_i=(1-m)(-1)^i+(m-1)^i$$
    复杂度还是(O(log n))但是常数小很多。

    (varphi(n))

    最好不要枚举因数然后暴力算(varphi(n))
    一种可行的方案是:先将(n)质因数分解,然后(dfs)搜出每一个因数,在搜的过程中自然可以求出它的(varphi)
    这样的话总的复杂度就是(O(a+T(sqrt a+d(n)log n)))

    你以为这样就做完了吗

    (nle10^{14})
    这样可能会产生一个问题:(n)(P=10^9+7)的倍数。这样算出来的分子要除以(n),不好意思不存在逆元。
    怎么办呢?
    我们把答案对(P^2)取模。如果(P|n),那么分子既然是(n)的倍数就也是(P)的倍数。直接除以(P),接着还需要除以(frac nP),而(frac nP)在模(P)意义下是存在逆元的((nle P^2)),于是就可以乘逆元了。

    code

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define ll long long
    const ll mod = 1000000007ll;
    const ll MOD = 1000000007ll*1000000007ll;
    const ll Inv6 = 833333345000000041ll;
    const int N = 10000005;
    int T,zhi[N],pri[N/10],tot,mu[N],cnt,q[30];ll n,m,p[30],ans;
    void add(ll &x,ll y){x+=y;if(x>=MOD)x-=MOD;}
    ll mul(ll x,ll y){
    	return (x*y-(ll)(((long double)x*y+0.5)/(long double)MOD)*MOD+MOD)%MOD;
    }
    ll sqr(ll x){return mul(x,x);}
    ll cub(ll x){return mul(mul(x,x),x);}
    ll fastpow(ll a,ll b){
    	ll res=1;
    	while (b) {if (b&1) res=mul(res,a);a=mul(a,a);b>>=1;}
    	return res;
    }
    ll fpow(ll a,ll b){
    	ll res=1;
    	while (b) {if (b&1) res=res*a%mod;a=a*a%mod;b>>=1;}
    	return res;
    }
    void init(){
    	mu[1]=1;
    	for (int i=2;i<N;++i){
    		if (!zhi[i]) pri[++tot]=i,mu[i]=-1;
    		for (int j=1;i*pri[j]<N;++j){
    			zhi[i*pri[j]]=1;
    			if (i%pri[j]) mu[i*pri[j]]=-mu[i];
    			else break;
    		}
    	}
    	for (int i=1;i<N;++i) mu[i]+=mu[i-1];
    }
    ll cal(ll n){
    	ll A=0,B=0;
    	for (ll i=1,j;i<=n;i=j+1){
    		j=n/(n/i);
    		add(A,mul(cub(n/i),mu[j]-mu[i-1]+MOD)%MOD);
    		add(B,mul(sqr(n/i),mu[j]-mu[i-1]+MOD)%MOD);
    	}
    	add(A,mul(B,3));add(A,2);return mul(A,Inv6);
    }
    ll F(ll n){
    	ll res=n&1?1-m:m-1;add(res,MOD);
    	add(res,fastpow(m-1+MOD,n));return res;
    }
    void dfs(int i,ll cur,ll phi){
    	if (i==cnt+1) {add(ans,mul(phi,F(n/cur)));return;}
    	dfs(i+1,cur,phi);
    	cur*=p[i];phi*=p[i]-1;dfs(i+1,cur,phi);
    	for (int j=2;j<=q[i];++j)
    		cur*=p[i],phi*=p[i],dfs(i+1,cur,phi);
    }
    int main(){
    	init();
    	scanf("%d",&T);while (T--){
    		scanf("%lld%lld",&n,&m);m=cal(m);
    		ll x=n;cnt=0;
    		for (int i=1;i<=tot&&(ll)pri[i]*pri[i]<=x;++i)
    			if (x%pri[i]==0){
    				p[++cnt]=pri[i];q[cnt]=0;
    				while (x%pri[i]==0) x/=pri[i],++q[cnt];
    			}
    		if (x>1) p[++cnt]=x,q[cnt]=1;
    		ans=0;dfs(1,1,1);
    		if (n%mod==0){
    			ans/=mod;
    			ans=ans*fpow(n/mod,mod-2)%mod;
    		}else{
    			ans%=mod;
    			ans=ans*fpow(n%mod,mod-2)%mod;
    		}
    		printf("%lld
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    metal的gpu query
    体积雾 global fog unity 及改进
    hdr rt format对颜色的影响
    unity deferred lighting
    unity linear space时 photoshop blend的正确设置
    unity linear work flow
    一些数据 bandwidth之类
    deferred rendering with msaa
    unity 显示mipmaplevel
    【转】在C#中使用SendMessage
  • 原文地址:https://www.cnblogs.com/zhoushuyu/p/9657640.html
Copyright © 2011-2022 走看看