This is true music.|

Wubaozi123awa

园龄:7个月粉丝:0关注:0

CSP-S可能出现的模板(手抄版)

CSP-S rp+++++++++++

前排提示,本篇文章带有注释~

数学

快速幂

int ksm(int a,int b,int p){
    int ret=1;
    while(b){
        if(b&1)ret=(ret*a)%p;
        a=(a*a)%p;
        b=b>>1;
    }
    return ret;
}
//b按位枚举 如果该位为1额外乘上a 每次a乘方

Lucas

int init(int a,int b){
    ny[1]=1;
    for(int i=2;i<N;i++)ny[i]=(mod-mod/i)*ny[mod%i]%mod;
    jcny[0]=jcny[1]=1;
    for(int i=2;i<N;i++)jcny[i]=jcny[i-1]*ny[i]%mod;
    jc[0]=jc[1]=1;
    for(int i=1;i<N;i++)jc[i]=jc[i-1]*i%mod;
}
//初始化 ny记录逆元 jcny记录逆元的阶乘 jc记录阶乘
int c(int a,int b){
    if(b>a)return 0;
    return jc[a]*jcny[a-b]%mod*jcny[b]%mod;
}
//用a!/(a-b!*b!)计算组合数
int lucas(int a,int b){
    if(!b)return 1;
    return c(a%mod,b%mod)*lucas(a/mod,b/mod)%mod;
}
//

exgcd

int exgcd(int a,int b,int &x,int &y){
    //这里注意引用 因为要修改值
    if(!b){
        //显而易见的当ax+0y=a时 x=1,y=0
        x=1,y=0;
        return a;
        int ret=exgcd(b,a%b,y,x);
        //exgcd的本质 ax+by=bx+(a%b)y
        y-=(a/b)*x;
        //exgcd的操作 x1=y2 y1=x2-(a/b)*x2
        return ret;
    }
}

exgcd求逆元

int inv(int a,int b){
    int x,y;
    int d=exgcd(a,m,x,y);
    return (d==1?(x+m)%m:-1);
}
//exgcd求逆元和线性同余方程道理相同

费马小定理求逆元

int inv(int a,int p){
    //根据 费马小定理 a^p与a在mod p意义下同余
    //可转为 a^p-2与a^-1在mod p意义下同余
    return ksm(a,p-2,p);
}

线性求逆元

for(int i=2;i<n;i++){
    int[i]=inv[p%i]*(p-p*i);
}

CRT

int crt(int k,int *a,int *r){
    int n=1,ans=0;
    for(int i=1;i<=k;i++)n=n*r[i];
    //计算所有模数的积
    for(int i=1;i<=k;i++){
        int m=n/r[i],b,y;//记 m=Sigma(模数)/该模数
        exgcd(m,r[i],b,y);//求解b*m mod r[i]=1得到m的逆元
        ans=(ans+a[i]*m*b)%n;//得到c[i]=m[i]*m[i]^-1,和a[i]相乘得到解
    }
    return (ans%n+n)%n;//取模~
}

exCRT

int excrt(int k,int *a,int *r){
    int m=a[i],ans=a[i];
    for(int i=2;i<=2;i++){
        int c=
    }
}

欧拉筛+处理欧拉函数

bool vis[N];
int p[N],phi[N],cnt=1;
void initphi(){
    phi[1]=1;
    for(int i=2;i<N;i++){
        if(!vis[i])p[cnt++]=i,phi[i]=i-1;
        //如果i并未被访问过i肯定为素数,素数的欧拉函数值为i-1
        for(int j=1,v;(v=i*p[j])<N;j++){
            vis[v]=1;
            if(i%p[j]==0){
                //如果p[j]为i的因子,则统计欧拉函数,并停下
                phi[i*p[j]]=phi[i]*p[j];
                break;
            }else phi[i*p[j]]=phi[i]*phi[p[j]];
        }
    }
}

Miller Rabin

//本模板超纲,但由于好用,建议死记硬背
bool Miller_Rabin(int n,int s){
    if(n==2)return 1;//2为唯一的偶质数,特判
    if(n<2||!(n&1))return 0;//其他偶数肯定是质数,1啥也不是
    int x,y,u=n-1,t=0;
    while((u&1)==0)t++,u>>1;
    for(int i=0;i<s;i++){//s为测试次数
        int a=rand()%(n-1)+1;
        int x=ksm(a,u,n);
        for(int j=0;j<t;j++){
            int y=ksm(x,x,n);
            if(y==1&&x!+1&&x!=n-1)return 0;
            x=y;
        }
    }
    if(x!=1)return 0;
}

欧拉函数 单个、

int euler(int n){
    int ret=n;
    for(int i=2;i*i<=n;i++){
        if(n%i==0){
            ret-=ret/i;
            while(!(n%i))n/=i;
        }
    }
    if(n>1)ret-=ret/n;
    return ret;
    //不用说什么,就是分解质因数
}

除法分块

for(int l=1,r;l<=n;l=r+1){
    r=(n/(n/l));
    cout<<n/l<<" "<<r-l+1<<endl;
}

高斯消元

int now=1;
for(int i=1;i<=n;i++){
    //TODO: 复习高斯消元
}

扫描线

//最终 到达了数学部分最长的模板,扫描线+线段树
//TODO: 在线段树模板写好后复习扫描线

数据结构~

单调栈

void insert(int x){
    while(!sta.empty()&&sta.top()<x)sta.pop();
    //维护单调性 不断pop掉不符合单调性的
    sta.push(x);
}

单调队列

deque<int>d;
for(int i=1;i<=n;i++){
    cin>>a;
    while(!d.empty()&&d.end()>a)d.pop_back();
    //维护单调性 不断pop掉不符合单调性的
    d.push_back(a);
}

01trie

int t[N*31][2],nv=1;
void build(int p,int d,int v){
    bool flag=(v&(1<<d));
    if(!t[p][flag])t[p][fkag]=++nv;
    if(d)build(t[p][flag],d-1,v);
    //递归逐位枚举
}
int query(int p,int d,int v){
    //查询按位异或
    if(d<0)return 0;
    bool flag(v&(1<<d));
    if(t[p][!flag])return (1<<d)+query(t[p][!flag],d-1,v);
    //不同为1
    if(t[p][!flag])return query(t[p][flag],d-1,v);
    //相同为0
}

ST表

int logn=21;
void pre(){
  Logn[1]=0;
  Logn[2]=1;
  for (int i=3;i<maxn;i++) {
    Logn[i] = Logn[i / 2] + 1;
  }
}
for(int j=1;j<=logn;j++){
    for(int i=1;i+(i<<j)-1<=n;i++){
        f[i][j]=max(f[i][j-1],f[i+(i<<(j-1))][j-1]);
    }
}

树状数组

#define lower_bit(x) (x)&-(x)
void add(int a,int c){
    for(int i=a;i<=n;i+=lower_bit(i))tree[i]+=c;
}
void add(int r){
    int ret=0;
    for(int i=r;i>=1;i-=lower_bit(i))ret+=tree[i];
}

线段树

本文作者:Wubaozi123awa

本文链接:https://www.cnblogs.com/baoziawa/p/18503374

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Wubaozi123awa  阅读(8)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起