大概是数学

快速幂

inline int power(int a,int b){
    int res=1;
    while(b){
        if(b&1)  res=res*a%mod;
        a=a*a%mod;b>>=1;
    }return res;
}

 

线性筛素数

inline void merge(){
    is[1]=1;
    for(int i=2;i<=n;i++){
        if(!is[i])  prime[++prime[0]]=i;
        for(int j=1;j<=prime[0]&&i*prime[j]<=n;++j){
            is[i*prime[j]]=1;
            if(!i%prime[j])  break;
        }
    }
}

质因数分解

 O(n1/4)

int power(__int128 a,int b,int c){
    __int128 m=1;a%=c;
    while(b){
        if(b&1)  m=m*a%c;
        b>>=1;a=a*a%c;
    }return m;
}long long gcd(long long a, long long b) 
{ 
     long long tmp; if(a<b) tmp=a,a=b,b=tmp;
     while(b) tmp=a%b, a=b, b=tmp;
     return a;
}bool isprime(long long p)
{
        static const int base[]={2,3,5,7,11,13,82,373};
        if(p<=20){
            return p==2||p==3||p==5||p==7||p==11||p==13||p==17||p==19;
        }
        int a=p-1,b=a; while(~b&1) b>>=1;
        for(int k=0;k<8;++k){
            if(base[k]%p==0) continue;
            if(p%base[k]==0) return 0;
            int v; for(int u=power(base[k],b,p),i=b;i^a;i<<=1,u=v) {
                v=(__int128)u*u%p;
                if(v==1) {
                    if(u!=1&&u!=p-1) return 0;
                    break;
                }
            } if(v^1) return 0;
        } return 1;
}void rho(long long n)
{
    srand(time(0));
  if(isprime(n)) { st[++top]=n; return; }
  __int128 x,y,z,c,d; int i,j;
  while(1){
    x=(__int128)rand()*rand()%(n-1)+1,
    c=(__int128)rand()*rand()%(n-1)+1;
    for(y=x,i=j=2; ; i++)
    {
      x=(x*x%n+c)%n;
      z=x-y; if(z<0) z=-z;
      d=gcd(z,n);
      if(d>1 && d<n) { rho(d); rho(n/d); return; }
      if(x==y) break;
      if(i==j) y=x,j<<=1;
    }
  }
}
pollard rho

扩展欧几里得(同余方程)

ll exgcd(ll a,ll b,ll &x,ll &y){
    if(!b){x=1;y=0;return a;}
    ll d=exgcd(b,a%b,x,y);
    ll t=x;x=y;y=t-a/b*y;
    return d;
}
int main(){
    a=read();b=read();p=read();
    ll d=exgcd(a,b,x,y);
    if(z%d){printf("Orz, I cannot find x!\n");continue;}
    f=((x*z/d)%p+p)%p;printf("%lld\n",f);
}

计算满足xa≡ b ( mod P )的最小非负整数;

xa-yp=b

欧拉函数

void euler(){
    var[1]=1;
    for(int i=2;i<n;++i){
        if(!is[i]){var[i]=i-1;prime[++prime[0]]=i;}
        for(int j=1;j<=prime[0];++j){
            int t=i*prime[j];
            if(t>n)  break;
            is[t]=1;var[t]=var[i]*var[prime[j]];
            if(i%prime[j]==0){
                var[t]=var[i]*prime[j];break;
            }            
        }
    }
}
View Code

 

purfer序列

构造

inline void TP(){
    for(int i=1;i<n;++i)  d[f[i]]++;
    for(int i=1,j=1;i<=n-2;++i,++j){
        while(d[j]) ++j;p[i]=f[j];
        while(i<=n-2&&!--d[p[i]]&&p[i]<j)  p[i+1]=f[p[i]],++i;
    }for(int i=1;i<=n-2;++i)  ans^=i*p[i];
}
inline void PT(){
    for(int i=1;i<=n-2;++i)  ++d[p[i]];
    p[n-1]=n;
    for(int i=1,j=1;i<n;++i,++j){
        while(d[j]) ++j;f[j]=p[i];
        while(i<n&&!--d[p[i]]&&p[i]<j)  f[p[i]]=p[i+1],++i;
    }for(int i=1;i<n;++i)  ans^=i*f[i];
}

 树的计数

void C_init(int n){
    for(int i=0;i<=n;++i){
        C[i][0]=1;C[i][i]=1;
        for(int j=1;j<i;++j)
            C[i][j]=(C[i-1][j-1]+C[i-1][j]);
    }
}
int main(){
    n=read();sum=n-2;C_init(n);
    for(int i=1;i<=n;++i)  d[i]=read();
    if(n==1&&d[1]==0){printf("1");return 0;} 
    for(int i=1;i<=n;++i)
        ans*=C[sum][d[i]-1],sum-=d[i]-1;
    if(sum!=0){printf("0");return 0;}
    printf("%lld",ans);
} 

 Bsgs

普通

 

c.clear();yy=read();z=read();p=read();
ll d=ceil(sqrt(p));ans=INT_MAX;yy%=p;z%=p; 
if(yy*z%p==0){printf("Orz, I cannot find x!\n");continue;}
for(ll i=0;i<=d;++i){
    k=qow(yy,i)*z%p;c[k]=i;
}for(ll i=0;i<=d;++i){
    k=qow(yy,i*d);
    if(c.count(k)&&i*d-c[k]>=0){ans=i*d-c[k];break;}
}if(ans==INT_MAX)  printf("Orz, I cannot find x!\n");
else  printf("%lld\n",ans);
View Code

莫比乌斯反演

莫比乌斯函数的计算

int mu[MAX],is[MAX],p[MAX];
inline void prime(){
    mu[1]=1;
    for(int i=2;i<=n;++i){
        if(!is[i]){
            p[++p[0]]=i;mu[i]=-1;
        }for(int j=1;j<=p[0]&&i*p[j]<=n;++j){
            is[i*p[j]]=1;
            if(!(i%p[j]))  break;
            mu[i*p[j]]=-mu[i];
        }
    }
}
View Code

 五

Lagrange 插值

O(n^2)还原多项式

inline void lag(){
    M[0]=1;
    for(int i=0;i<=n;++i)
        for(int j=i+1;j>=0;--j)
            M[j]=((j?M[j-1]:0)-M[j]*i)%mod;
    for(int i=0;i<=n;++i){
        int qwe=f[i]*f[n-i]%mod*(((n-i)&1)?-1:1),ert=M[n+1];
        qwe=power(qwe,mod-2)*Y[i]%mod;
        for(int j=n;j>=0;--j){
            g[j]=(g[j]+qwe*ert)%mod;ert=(ert*i+M[j])%mod;
        }
    }
}
横坐标是连续整数

 

O(nlogn)插值

inline int qm(int x){return x>mod?x-mod:x;}
inline int power(int a,int b){
    int res=1;a=qm(a+mod);
    while(b){
        if(b&1)  res=1ll*res*a%mod;
        a=1ll*a*a%mod;b>>=1;
    }return res;
}inline int lag(int U,int X){
    int res=0,abc,def;pre[0]=suf[X+3]=1;
    for(int i=1;i<=X;++i)   pre[i]=1ll*pre[i-1]*(U-i+mod)%mod;
    for(int i=X;i;--i)  suf[i]=1ll*suf[i+1]*(U-i+mod)%mod;
    for(int i=1;i<=X;++i){
        abc=1ll*y[i]*pre[i-1]%mod*suf[i+1]%mod;
        def=1ll*f[i-1]*f[X-i]%mod*(((X-i)&1)?-1:1);
        res=qm(res+1ll*abc*power(def,mod-2)%mod);
    }return res;
}
横坐标是连续整数
posted @ 2023-02-01 14:52  yisiwunian  阅读(29)  评论(0编辑  收藏  举报