• [bzoj 1951] [Sdoi2010]古代猪文


    传送门

    Description

    给定两个数(N)(G) ((N,Gleq 10^9)),求

    [ans=G^{sum_{d|N} binom{N}{d}} (mod 999911659) ]

    Solution

    1. 运用欧拉定理,所以指数只需要$sum_{d|N} binom{N}{d} mod 999911658 $
    2. 运用(Lucas)定理,( binom{m}{n} equiv binom{m/p}{n/p} binom{m\%p}{n\%p} mod p),其中(p)是个质数
    3. 但是(999911658)并不是个质数,不能用(Lucas)定理。这时我们把它分解:(999911658=2*3*4679*35617),对这(4)个质因子分别求解出它的答案(X[i]),原问题转化成一个解线性方程组的问题,因为(999911658)比较小,所以直接用中国剩余定理即可解决。

    [G的指数=sum X[i] left ( frac{M}{p_i} ight )^{-1}_{p_i} frac{M}{m_i} ]


    Code 

    #include<bits/stdc++.h>
    #define ll long long
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    inline ll read()
    {
    	ll x=0,f=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    	return x*f;
    }
    #define mod 999911659
    #define Mod 999911658
    #define MN 35620
    ll N,G,mo,X[4],fac[MN],inv[MN];
    const int p[4]={2,3,4679,35617};
    ll C(ll n,ll m)
    {
    	if(n<m) return 0ll;
        if(n<mo&&m<mo) return fac[n]*inv[m]%mo*inv[n-m]%mo;
        return C(n%mo,m%mo)*C(n/mo,m/mo)%mo;
    }
    void exgcd(ll a,ll b,ll &d,ll &x,ll &y)
    {
        if(!b) return (void)(d=a,x=1,y=0);
        exgcd(b,a%b,d,y,x);y-=x*(a/b);
    }
    ll CRT()
    {
        ll ret=0,d,x,y;register int i;
        for(i=0;i<4;++i)
    	{
            exgcd(Mod/p[i],p[i],d,x,y);
            ll INV=(x%Mod+Mod)%Mod;
            (ret+=INV*X[i]%Mod*(Mod/p[i])%Mod)%=Mod;
        }
        return ret;
    }
    ll fpow(ll x,ll m)
    {
    	ll ret=1;
    	for(;m;x=x*x%mod,m>>=1) if(m&1) ret=ret*x%mod;
    	return ret;
    }
    int main()
    {
    	N=read();G=read();
    	register int i,T;
    	for(T=0;T<4;++T)
    	{
        	mo=p[T];fac[0]=1;
            for(i=1;i<mo;++i) fac[i]=fac[i-1]*i%mo;
    		inv[mo-1]=mo-1;
    		for(i=mo-2;~i;--i) inv[i]=inv[i+1]*(i+1)%mo;
        	for(i=1;i*i<=N;++i)
    		{
            	if(N%i) continue;
            	(X[T]+=C(N,i))%=mo;
            	if(N/i-i) (X[T]+=C(N,N/i))%=mo;
        	}
    	}
    	printf("%lld
    ",fpow(G,CRT()));
    	return 0;
    }
    


    Blog来自PaperCloud,未经允许,请勿转载,TKS!

  • 相关阅读:
    (原创)批处理中变量的用法
    (收藏)Android 的各种listener and states event
    (转)Android 、BlackBerry 文本对齐方式对比
    (转)Android中尺寸单位杂谈
    批处理文章集锦
    Launch custom android application from android browser
    【原创】我的批处理命令例子
    Android文字居中
    (转)androd之绘制文本(FontMetrics)
    (批处理之二):setlocal enabledelayedexpansion (详解)
  • 原文地址:https://www.cnblogs.com/PaperCloud/p/10245403.html
Copyright © 2020-2023  润新知