zoukankan      html  css  js  c++  java
  • [BZOJ3283]运算器

    description

    BZOJ

    solution

    (exbsgs+exlucas+excrt)模板题。
    写到手炸...

    #include<bits/stdc++.h>
    #define FL "3283"
    using namespace std;
    typedef long long ll;
    const int N=1e5+10;
    const int mod1=1e6+3;
    const int mod2=998244353;
    inline int read(){
      int data=0,w=1;char ch=getchar();
      while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
      if(ch=='-')w=-1,ch=getchar();
      while(ch<='9'&&ch>='0')data=data*10+ch-48,ch=getchar();
      return data*w;
    }
    inline void file(){
      freopen(FL".in","r",stdin);
      freopen(FL".out","w",stdout);
    }
    
    namespace math{
      inline int gcd(int a,int b){return b?gcd(b,a%b):a;}
      inline void exgcd(int a,int b,int &x,int &y,int &d){
        if(!b){d=a;x=1;y=0;return;}exgcd(b,a%b,y,x,d);y-=a/b*x;
      }
      inline int inv(int a,int p){
        int x,y,d;exgcd(a,p,x,y,d);return (x%p+p)%p;
      }
      inline int poww(int a,int b,int mod){
        int res=1;
        for(;b;b>>=1,a=1ll*a*a%mod)
          if(b&1)res=1ll*res*a%mod;
        return res;
      }
      inline int excrt(int n,int *a,int *p){
        for(int i=2,x,y,d,L;i<=n;i++){
          exgcd(p[1],p[i],x,y,d);L=p[1]/d*p[i];
          x=(1ll*x*(a[i]-a[1])%p[i]+p[i])%p[i];
          a[1]=(1ll*x*p[1]%L+a[1])%L;p[1]=L;
        }
        return a[1];
      }
    }
    using math::inv;
    using math::poww;
    using math::excrt;
    using math::gcd;
    
    namespace HASH{
      int head[mod1],nxt[N],to[N],val[N],cnt;
      inline void init(){memset(head,-1,sizeof(head));while(cnt)head[cnt--]=-1;}
      inline void insert(int a,int b){
        to[++cnt]=b;val[cnt]=a%mod2;
        nxt[cnt]=head[a%mod1];head[a%mod1]=cnt;
      }
      inline int find(int a){
        int r=-1;
        for(int i=head[a%mod1];i!=-1;i=nxt[i])
          if(a%mod2==val[i]){
    	if(r==-1)r=to[i];
    	else r=min(r,to[i]);
          }
        return r;
      }
    }
    using HASH::init;
    using HASH::insert;
    using HASH::find;
    
    namespace Exbsgs{
      inline int logmod(int a,int b,int p){
        int q=sqrt(p)+1;init();
        for(int i=0,r=1%p;i<=q;i++,r=1ll*r*a%p)insert(r,i);
        for(int i=0,v=inv(poww(a,q,p),p),r;i<=q;i++,b=1ll*b*v%p)
          if(r=find(b),r!=-1)return i*q+r;
        return -1;
      }
      inline int exbsgs(int a,int b,int p){
        int cnt=0,r=1,d;
        while(gcd(a,p)!=1){
          if(r==b)return cnt;
          d=gcd(a,p);
          if(b%d)return -1;
          b/=d;p/=d;r=1ll*r*(a/d)%p;cnt++;
        }
        return logmod(a,1ll*b*inv(r,p)%p,p)+cnt;
      }
    }
    using Exbsgs::exbsgs;
    
    namespace Exlucas{
      int p[20],pk[20],fac[20][N],r[20],tot;
      inline void fact(int x){
        tot=0;
        for(int i=2;i*i<=x;i++)
          if(x%i==0){
    	p[++tot]=i;pk[tot]=1;
    	while(x%i==0)pk[tot]*=i,x/=i;
          }
        if(x>1)tot++,p[tot]=pk[tot]=x;
        for(int i=1;i<=tot;i++){
          fac[i][0]=1;
          for(int j=1;j<=pk[i];j++)
    	fac[i][j]=1ll*fac[i][j-1]*(j%p[i]?j:1)%pk[i];
        }
      }
      inline int mul(int i,int n){
        int res=poww(fac[i][pk[i]],n/pk[i],pk[i]);
        for(int j=n/pk[i]*pk[i]+1;j<=n;j++)
          res=1ll*res*(j%p[i]?j:1)%pk[i];
        return 1ll*res*(n/p[i]?mul(i,n/p[i]):1)%pk[i];
      }
      inline int exlucas(int n,int m,int mod){
        if(n<m)return 0;fact(mod);
        for(int i=1;i<=tot;i++){
          int a=mul(i,n),b=mul(i,m),c=mul(i,n-m),k=0;
          for(int j=n;j;j/=p[i])k+=j/p[i];
          for(int j=m;j;j/=p[i])k-=j/p[i];
          for(int j=n-m;j;j/=p[i])k-=j/p[i];
          r[i]=1ll*a*inv(b,pk[i])%pk[i]*inv(c,pk[i])%pk[i]*poww(p[i],k,pk[i])%pk[i];
        }
        return excrt(tot,r,pk);
      }
    }
    using Exlucas::exlucas;
    
    int main()
    {
      init();
      int T=read();
      while(T--){
        int opt=read(),y=read(),z=read(),p=read(),r;
        if(opt==1)printf("%d
    ",poww(y,z,p));
        if(opt==2){
          r=exbsgs(y,z,p);
          r==-1?puts("Math Error"):printf("%d
    ",r);
        }
        if(opt==3)printf("%d
    ",exlucas(z,y,p));
      }
      return 0;
    }
    
  • 相关阅读:
    HDU 4472 Count DP题
    HDU 1878 欧拉回路 图论
    CSUST 1503 ZZ买衣服
    HDU 2085 核反应堆
    HDU 1029 Ignatius and the Princess IV
    UVa 11462 Age Sort
    UVa 11384
    UVa 11210
    LA 3401
    解决学一会儿累了的问题
  • 原文地址:https://www.cnblogs.com/cjfdf/p/10169353.html
Copyright © 2011-2022 走看看