• [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;
    }
    
  • 相关阅读:
    dockerk个人学习(0)
    ubuntu编译python源码的坑
    查找大目录
    ubuntu 远程gui显示
    paramiko模块
    python open和file的区别
    python type metaclass
    python 生成器 迭代器 yiled
    博客暂停更新,请移步新主页
    win10禁用自动更新服务
  • 原文地址:https://www.cnblogs.com/cjfdf/p/10169353.html
Copyright © 2020-2023  润新知