zoukankan      html  css  js  c++  java
  • P2480 SDOI 古代猪文(自带其他详细基础数论)

    P2480 SDOI2010古代猪文

    题目大意:求

    (G^{sum_{d|n}{n choose d}}~mod~999911659)

    各种基础数论全家桶,做这个题相当于复习今天内容了

    999911659为质数

    费马小定理(a^pequiv a(mod~p)),(a^p~mod~p=a~mod~p)

    (p是质数时,φ(p)=p-1,根据欧拉定理推论a^bequiv a^{b~mod~φ(n)}=a^{b~mod~(p-1)}(mod~n))

    化简可得(a^{sum d|nC_n^d~mod~999911658}mod999911659)

    质因数分解(999911658 = 2*3*4679*35617)

    (枚举每个d,再用个Lucas定理或其他鬼方法把C_n^d算出来,分别计算sum C_n^d对四个质数取模结果记为a_1,a_3,a_3,a_4)

    跑个中国剩余定理

    中国剩余定理:(m_i是两两互质的整数,m=prod_{i=1}^nm_i,M_i=m/m_i,t_i)是线性同余方程(M_it_iequiv1(mod~m_i))

    的一个解,对于任意的n个整数(a_i),方程组有整数解为(x=sum_{i=1}^na_iM_it_i)

    [left{ egin{aligned} x & equiv a_1(mod~2) \ x & equiv a_2(mod~3) \ x&equiv a_3(mod~4679)\ x&equiv a_4(mod~35617)\ end{aligned} ight. ]

    #include<cstdio>
    #define maxn
    #define mod 999911658
    #define int long long
    using namespace std;
    int n,G,jc[40000],a[5],b[5]={0,2,3,4679,35617},ans;
    inline int qpow(int a,int k,int p)
    {
    	int res=1;
    	while(k)
    	{
    		if(k&1) res=(res*a)%p;
    		a=(a*a)%p;
    		k>>=1;
    	}
    	return res%p;
    }
    void jiecheng(int p){
    	jc[0] = 1;
    	for(int i = 1;i<=p;i++)
    	jc[i] = jc[i-1] * i % mod;
    }
    int C(int n,int m,int p){
    	if(n < m) return 0;
    	return jc[n] * qpow(jc[m],p-2,p) % p * qpow(jc[n-m],p-2,p) % p;
    }
    int lucas(int n,int m,int p){
    	if(n<m) return 0;if(!n) return 1;
    	return lucas(n/p,m/p,p)*C(n % p,m % p,p) % p;
    }
    void zgsy(){
    	for(int i=1;i<=4;i++)
    	ans=(ans+a[i]*(mod/b[i])%mod*qpow(mod/b[i],b[i]-2,b[i]))%mod;
    }
    signed main(){
    	scanf("%lld%lld",&n,&G);
    	if(G%(mod+1)==0){
    		printf("0
    ");
    		return 0;
    	}//特判
    	for(int k=1;k<=4;k++){
    		jiecheng(b[k]);
    		for(int i=1;i*i<=n;i++){
    			if(n%i==0){
    				a[k]=(a[k]+lucas(n,i,b[k]))%b[k];
    				if(i*i!=n){
    					a[k]=(a[k]+lucas(n,n/i,b[k]))%b[k];
    				}
    			}
    		}
    	}//逐一枚举n的约数
    	zgsy();
    	printf("%lld
    ",qpow(G,ans,mod+1));//注意mod要+1
    	return 0;
    }
    

    [计算组合数的几种方法:\ 1.递推杨辉三角C_n^m=C_{n-1}^m+C_{n-1}^{m-1}~C[0][0]=C[1][0]=1,求一个组合数可以滚动,倒着枚举,代码如下\ 2.乘法逆元:**这种方法只适用于对答案模一个大质数的情况**,根据通项公式预处理阶乘算逆元乱搞\ 质数一定要大\ 3.Lucas定理:C_n^m=C_{n/p}^{m/p}*C_{n\%p}^{m\%p}(mod~p)\ 4.质因数分解,要乘或除的每一个数分解质因数,再把分母的质因数减掉,最后把剩下的质因数乘起来,边乘边模p ]

    //一维递推组合数
    	cin>>n>>m;
        m=min(m,n-m);
        c[0]=1;
        for (int i=1;i<=n;i++)
        {
            for (int j=m;j>=1;j--)
        	c[j]=c[j]+c[j-1];
        }
        cout<<c[m];
    //线性推逆元
    long long inv[10000005];
    inv[1]=1;
    long long ny(int x,int p)
    {
        if (inv[x] != 0) return inv[x];
        inv[x]=(p - p / x) * ny(p % x,p) % p;
        return inv[x];
    }
    //费马小定理求逆元 a mod p乘法逆元=a^(p-2)
    快速幂`````
    qpow(a,p-2)
    //扩欧
    void exgcd(LL a, LL b, LL &x, LL &y)    //拓展欧几里得算法
    {
        if(!b) x = 1, y = 0;
        else
        {
            exgcd(b, a % b, y, x);
            y -= x * (a / b);
        }
    }
    LL niYuan(LL a, LL b)   //求a对b取模的逆元
    {
        LL x, y;
        exgcd(a, b, x, y);
        return (x + b) % b;
    }
    

    [xequiv1(mod~3)\ xequiv1(mod~5)\ xequiv2(mod~7)\ xequiv b_i(mod~a_i) \ a=prod_i^na_i,A_i=a/a_i,t_i是方程A_it_iequiv1(mod~a_i)的解\ 方程组的解为x=sum_{i=1}^nb_iA_it_i ]

    //曹冲养猪
    #include<iostream>
    #define ll long long
    using namespace std;
    int a[11],b[11],n;
    ll mul = 1,t;
    inline void Exgcd(ll a,ll b,ll &d,ll &x,ll &y){
    	if(!b){d=a;x=1;y=0;}
    	else{
    		Exgcd(b,a%b,d,x,y);
    		ll t=x;x=y;y=t-(a/b)*y;
    	}
    }
    int main(){
    	std::cin>>n;
    	ll ans=0,t,x,y,d;;
    	for(int i = 1;i <= n;i++){
    		std::cin>>a[i]>>b[i];
    		mul *= a[i];
    	}
    	for(int i = 1;i <= n;i++) {
    	t = mul / a[i];
    	Exgcd(t,a[i],d,x,y);
    	ans=((ans+t*x*b[i])%mul+mul)%mul;
    	}
    	std::cout<<(ans+mul) % mul;
    }
    

    计算器

    BSGS,快速求出(a^xequiv b(mod~p))的最小非负整数解

    (x)拆分成(i*m-j)形式,(m为sqrt(p)上取整,原式化成a^{i*m-j}equiv b(mod~p))

    (a^{i*m}equiv b*a^j(mod~p)),从(0-m)枚举(i),算出所有的(a^{i*m})

    如果一个对应的(a^{i*m})的值已经在哈希表,则表明(i*m-j)为一个解,输出此时的解

    因为(jle m),所以求出的解随(i)的增大而减小,所以最先求出(i)所对应的解,即为所求






    (aequiv b(mod~n)Leftrightarrow n|(a-b))

    (aequiv b(mod~n),cequiv d(mod~n)Leftrightarrow a±cequiv b±d(mod~n))

    (⇔acequiv bd(mod~n)⇔kaequiv kb(mod~n)⇔a^mequiv b^m)

    (gcd(a,n)=1)(abequiv ac(mod~n)⇔bequiv c(mod~n))

    (φ(n)=sum_{i=1}^n[gcd(i,n)=1][为布尔式],φ(1)=1,φ(p)=p-1,pin prime)

    对于质数 pk 次方 (p^k)显然:小于等于它的数一共 (p^k)个,只有含有质因数 p的数与它不互质,这些数为:

    (p,2p,3p⋯p^{k-1}⋅p)(p-1)个,(故φ(p^k)=p∈Prime,k∈Z+)

    同时还能得到递推式:(φ(p^{k+1})=p^{k+1}-p^k=p(p^k-p^{k-1})=p*φ(p^k))

    欧拉函数筛法:

    [φ(p*n)=φ(n)*(p|n)~?~p:(p-1) ]

    (a^{p-1}equiv1(mod~p))可得(a^{n}equiv a^{n~mod~(p-1)}(mod~p))

    欧拉定理:(gcd(a,m)=1可以得到a^{φ(m)}equiv1(mod~m))

    推论(a^{n}equiv(a~mod~m)^{(n~mod~φ(m))}(mod~m))

    img

  • 相关阅读:
    poj 3040 Allowance
    poj 2393 Yogurt factory
    【BZOJ1833】数字计数(ZJOI2010)-数位DP
    【BZOJ4820】硬币游戏(SDOI2017)-概率+高斯消元+KMP
    【BZOJ3626】LCA(LNOI2014)-树链剖分+离线处理
    【BZOJ4817】树点涂色(SDOI2017)-LCT+LCA+线段树
    【BZOJ1135】LYZ(POI2009)-线段树+Hall定理
    【CF392D】Three Arrays-set+multiset
    【51Nod1688】LYKMUL-线段树+乘法原理
    【BZOJ2956】模积和-数论分块
  • 原文地址:https://www.cnblogs.com/shikeyu/p/13369096.html
Copyright © 2011-2022 走看看