zoukankan      html  css  js  c++  java
  • codeforces2015ICL,Finals,Div.1#J Ceizenpok’s formula 扩展Lucas定理 扩展CRT

    默默敲了一个下午,终于过了,

    题目传送门

    扩展Lucas是什么,就是对于模数p,p不是质数,但是不大,如果是1e9这种大数,可能没办法,

    对于1000000之内的数是可以轻松解决的。

    题解传送门

    代码完全手写,直接写了扩展的中国剩余定理(普通的不会写)

    题意:给你n,m,p 求C(n,m)%p

      1 #include<cstring>
      2 #include<cmath>
      3 #include<cstdio>
      4 #include<iostream>
      5 #include<algorithm>
      6 
      7 #define ll long long
      8 #define N 27
      9 using namespace std;
     10 inline ll read()
     11 {
     12     ll x=0,f=1;char ch=getchar();
     13     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
     14     while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
     15     return x*f;
     16 }
     17 
     18 ll n,m,p,ans,Modulo;
     19 ll prime[N],num[N],mod[N];
     20 int tot;
     21 
     22 void get_factor(ll p)
     23 {
     24     int up=(int)sqrt(p);
     25     for (int i=2;i<=up;i++)
     26     {
     27         if (p%i==0)
     28         {
     29             prime[++tot]=i,mod[tot]=1;
     30             while(p%i==0)
     31             {
     32                 p/=i;
     33                 num[tot]++;
     34                 mod[tot]*=i;
     35             }
     36         }
     37     }
     38     if (p>1) num[++tot]=1,prime[tot]=mod[tot]=p;
     39 }
     40 ll fast_pow(ll a,ll b,ll mod)
     41 {
     42     ll ans=1;
     43     while(b)
     44     {
     45         if (b&1) (ans*=a)%=mod;
     46         (a*=a)%=mod;
     47         b>>=1;
     48     }
     49     return ans;
     50 }
     51 ll Recursion(ll n,ll x)
     52 {
     53     if (!n) return 1;
     54     ll dw=1;
     55     for (ll i=1;i<=mod[x];i++)
     56         if (i%prime[x]!=0) (dw*=i)%=mod[x];
     57     ll res=fast_pow(dw,n/mod[x],mod[x]);
     58     for (ll i=n/mod[x]*mod[x]+1;i<=n;i++)
     59         if (i%prime[x]!=0) (res*=i%mod[x])%=mod[x];
     60     return (res*Recursion(n/prime[x],x))%mod[x];    
     61 }
     62 void Ex_gcd(ll a,ll b,ll &x,ll &y)
     63 {
     64     if (!b)
     65     {
     66         x=1,y=0;
     67         return;
     68     }
     69     else
     70     {
     71         Ex_gcd(b,a%b,x,y);
     72         ll t=x;x=y;y=t-a/b*y;
     73     }
     74 }
     75 ll Inv(ll a,ll b)
     76 {
     77     ll x,y;
     78     Ex_gcd(a,b,x,y);
     79     if (x<0) x+=b;
     80     return x;
     81 }
     82 ll get_combination(ll x)
     83 {
     84     ll ans=Recursion(n,x),k=0;
     85     for (ll i=n;i;i/=prime[x]) k+=i/prime[x];
     86     for (ll i=m;i;i/=prime[x]) k-=i/prime[x];
     87     for (ll i=n-m;i;i/=prime[x]) k-=i/prime[x];
     88     ans*=fast_pow(prime[x],k,mod[x]);
     89     ans%=mod[x];
     90     ll res1=Recursion(m,x),res2=Recursion(n-m,x);
     91     ans*=Inv(res1,mod[x]),ans%=mod[x];
     92     ans*=Inv(res2,mod[x]),ans%=mod[x];
     93     return ans;
     94 }
     95 void combine(ll &a,ll &b,ll c,ll d)
     96 {
     97     ll inv=Inv(b,d)*(c-a)%d;
     98     a=inv*b+a,b=b*d,a%=b;
     99 }
    100 int main()
    101 {
    102     freopen("fzy.in","r",stdin);
    103     freopen("fzy.out","w",stdout);
    104     
    105     n=read(),m=read(),p=read();
    106     get_factor(p);
    107     ans=get_combination(1),Modulo=mod[1];
    108     for (int i=2;i<=tot;i++)
    109     {
    110         ll res=get_combination(i),new_mod=mod[i];
    111         combine(ans,Modulo,res,new_mod);
    112     }
    113     printf("%lld
    ",(ans%Modulo+Modulo)%Modulo);
    114 }
  • 相关阅读:
    你必须知道的495个C语言问题,学习体会四
    ++操作符重载代码分析
    正斜杠 与反斜杠之争
    文件操作基础入门
    你必须知道的495个C语言问题,学习体会三
    你必须知道的495个C语言问题,学习体会二
    【皇甫】☀别进来 千万别进来
    【皇甫】☀设计_模式
    【皇甫】☀七个小矮人和一个小博
    【皇甫】☀游戏还有游戏还是游戏
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8631704.html
Copyright © 2011-2022 走看看