模板

PS:以后把模板就放这里了~qwq

常用定义

#define M(a,b) memset(a,(b),sizof(a))
#define F(i,a,b) for(register int i=(a);i<=(b);i++)
#define R(i,a,b) for(register int i=(b);i>=(a);i--)
#define E(i,u) for(register int i=head[u];i;i=nxt[i])
typedef long long LL;

数学

筛法

线性筛质数
void getpri() {
    int tot=0;
    for(int i=2;i<=n;i++) {
        if(!vis[i]) pri[++tot]=i;
        for(int j=1;i*j<=n&&j<=cnt;j++) {
            vis[i*pri[j]]=1;
            if(i%pri[j]==0) break;
        }
    }
}
欧拉函数
void getphi() {
    int tot=0;
    for(int i=2;i<=n;i++) {
        if(!vis[i]) pri[i]=i,phi[i]=i-1;
        for(int j=1;j<=tot&&i*j<=n;j++) {
            vis[i*pri[j]]=1;
            if(i%pri[j]==0) {
                phi[i*pri[j]]=phi[i]*pri[j];
                break;
            } 
            phi[i*pri[j]]=phi[i]*(pri[j]-1);
        }
    }
}
莫比乌斯函数
void getmu() {
    int tot=0;
    for(int i=1;i<=n;i++) {
        if(!vis[i]) pri[++tot]=i,mu[i]=-1;
        for(int j=1;j<=tot&&i*j<=n;j++) {
            vis[i*pri[j]]=1;
            if(i%pri[j]==0) break;//mu[i*pri[j]]=0;
            mu[i*pri[j]]=-mu[i];
        }
    }
}

快速幂

typedef long long LL;
LL qpow(LL a,LL b) {//无模数 
    LL t=1;
    while(b) {
        if(b&1) t*=a;
        a*=a; b>>=1;
    }
    return t;
}

LL qpow(LL a,LL b,LL q) {//有模数 
    LL t=1;
    while(b) {
        if(b&1) t=t*a%p;
        a=a*a%p; b>>=1;
    }
    return t;
}

矩阵乘法&快速幂

#define F(i,a,b) for(register int i=(a);i<=(b);i++)
#define M(a,b) memset(a,(b),sizof(a))
const int N=510;
int n;
struct Matrix{
    int da[N][N];
    void clear() {M(da,0);}
    Matrix operator * (const Matrix oth) {
        Matrix t;
        F(i,1,n) F(j,1,n) F(k,1,n) 
            t.da[i][j]=da[i][k]*oth.da[k][j];
        return t;
    }
}

Matrix Qpow(Matrix a,int b) {//快速幂
    Matrix t;
    F(i,1,n) t.da[i][i]=1;
    while(b) {
        if(b&1) t=t*a;
        a=a*a; b>>=1;
    }
    return t;
}

字符串

AC自动机

queue <int> Q;
struct Aho_Corasick_Automation{
    int nd[N][26],val[N],fail[N],cnt;
    void ins(char *s) {
        int len=strlen(s),now=0;
        F(i,0,len-1) {
            int v=s[i]-'a';
            if(!nd[now][v]) nd[now][v]=++cnt;
            now=nd[now][v];
        }
        val[now]++;
    }
    void build() {
        F(i,0,26-1) if(nd[0][i]) fail[nd[0][i]]=0,Q.push(nd[0][i]);
        while(!Q.empty()) {
            int u=Q.front(); Q.pop();
            F(i,0,26-1) 
                if(nd[u][i]) fail[nd[u][i]]=nd[fail[u]][i],Q.push(nd[u][i]);
                    else nd[u][i]=nd[fail[u]][i];
        }
    }
    int query(char *s) {
        int len=strlen(s),now=0,ans=0;
        F(i,0,len-1) {
            now=nd[now][s[i]-'a'];
            for(int t=now;t&&~val[t];t=fail[t]) ans+=val[t],val[t]=-1;
        }
        return ans;
    }
}AC;

数据结构

左偏树

int nd[N][2],dis[N],val[N],fa[N];

#define ls nd[x][0]
#define rs nd[x][1]
int merge(int x,int y) {
    if(!x||!y) return x+y;
    if(val[x]>val[y]||(val[x]==val[y]&&x>y)) swap(x,y);
    fa[rs=merge(rs,y)]=x;
    if(dis[ls]<dis[rs]) swap(ls,rs);
    dis[x]=dis[rs]+1;
    return x;
}

void pop(int x) {
    val[x]=-1; fa[ls]=fa[rs]=0;
    merge(ls,rs);
}

int getf(int x) {
    while(fa[x]) x=fa[x]; return x;
}

其他

高精度

(希望没错qwq)
PS:建议复制下来查看~

struct bign{
    int len,s[MAXL]; bool sign;
    bign() {M(s,0);len=sign=1;}
    bign(const char *num) {*this=num;}
    bign(int num) {*this=num;};
    string tostr() const {
        string res="";
        F(i,0,len-1) res=(char)(s[i]+'0')+res;
        if(res=="") res="0";
        if(!sign&&res!="0") res="-"+res;
        return res;
    }
    friend istream &operator>>(istream &in,bign &num) {string str;in>>str;num=str;return in;}
    friend ostream &operator<<(ostream &out,bign &num) {out<<num.tostr();return out;}
    bign operator=(const char *num) {
        M(s,0);
        char a[MAXL]="";
        if(num[0]!='-') strcpy(a,num);
        else { int Len=strlen(num);
            F(i,1,Len-1) a[i-1]=num[i];
        }
        sign=!(num[0]=='-');
        len=strlen(a);
        F(i,0,len-1) s[i]=a[len-i-1]-48;
        return *this;
    }
    bign operator=(int num) {char tmp[MAXL]; sprintf(tmp,"%d",num); *this=tmp;return *this;}
    bign operator=(const string num) {const char *tmp; tmp=num.c_str(); *this=tmp; return *this;}
    bool operator<(const bign &num) const {
        if(sign^num.sign) return num.sign;
        if(len!=num.len) return len>num.len;
        R(i,0,len-1) if(s[i]!=num.s[i]) 
            return sign?(s[i]<num.s[i]):(!(s[i]<num.s[i]));
        return !sign;
    }   
    bool operator>(const bign &num) const {return num<*this;}
    bool operator<=(const bign &num) const {return !(*this>num);}
    bool operator>=(const bign &num) const {return !(*this<num);}
    bool operator!=(const bign &num) const {return *this>num||*this<num;}
    bool operator==(const bign &num) const {return !(*this!=num);}
    bign operator+(const bign &num) const {
        if(sign^num.sign) {
            bign tmp=sign?num:*this;
            tmp.sign=1;
            return sign?*this-tmp:num-tmp;
        }
        bign res;
        int tmp=res.len=0;
        for(register int i=0;tmp||i<(max(len,num.len));i++) {
            int t=s[i]+num.s[i]+tmp;
            res.s[res.len++]=t%10;
            tmp=t/10;
        }
        return res;
    }
    bign operator++() {*this=*this+1;return *this;}
    bign operator++(int) {bign old=*this;++(*this);return old;}
    bign operator+=(const bign &num) {*this=*this+num;return *this;}
    bign operator-(const bign &num) const {
        bign b=num,a=*this;
        if(!num.sign&&!sign) {b.sign=a.sign=1;return b-a;}
        if(!b.sign) {b.sign=1;return a+b;}
        if(!a.sign) {a.sign=1;b=bign(0)-(a+b);return b;}
        if(a<b) {bign c=(b-a);c.sign=0;return c;}
        bign res; res.len=0;
        for(int i=0,g=0;i<a.len;i++) {
            int x=a.s[i]-g;
            if(i<b.len) x-=b.s[i];
            if(x>=0) g=0;
            else g=1,x+=10;
            res.s[res.len++]=x;
        }
        res.clean();
        return res;
    }
    bign operator*(const bign &num) const {
        bign res; res.len=len+num.len;
        F(i,0,len-1) F(j,0,num.len-1) res.s[i+j]+=s[i]*num.s[j];
        F(i,0,res.len-1) {res.s[i+1]+=res.s[i]/10; res.s[i]%=10;}
        res.clean();
        res.sign=!(sign^num.sign);
        return res;
    }
    bign operator*(const int num) const {bign a=num,b=*this;return a*b;}
    bign operator*=(const bign &num) {*this=*this*num;return *this;}
    bign operator/(const bign &num) const {
        bign res; res.len=len-num.len+1;
        if(res.len<0) {res.len=1;return res;}
        bign dis=*this,did=num;//divisor divid
        dis.sign=did.sign=1;
        int k=res.len-1,j=len-1;
        while(k>=0) {
            while(!dis.s[j]) j--;
            if(k>j) k=j;
            char reg[MAXL]; M(reg,0);
            R(i,k,j) reg[j-i]=dis.s[i]+'0';
            bign die=reg;//dividend
            if(die<did) {k--;continue;}
            int key=0;
            while(did*key<=die) key++;
            key--;
            res.s[k]=key;
            bign tmp=did*key;
            F(i,0,k-1) tmp=tmp*10;
            dis=dis-tmp;
            k--;
        }
        res.clean();
        res.sign=!(sign^num.sign);
        return res;
    }
    bign operator/=(const bign &num) {*this=*this/num;return *this;}
    bign operator%(const bign &num) {
        bign a=*this,b=num; a.sign=b.sign=1;
        bign res,tmp=a/b*b;
        res=a-tmp; res.sign=sign;
        return res;
    }
    void clean() {if(len==0)len++; while(len>1&&s[len-1]=='\0')len--;}
    bign pow(const bign& num) {bign res=1; for(bign i=0;i<num;i++) res=res*(*this); return res;}
    bign fac()const {bign res=1; for(bign i=1;i<=*this;i++) res=res*i; return res;}
    bign sqrt()const {
        if(*this<0) return -1;
        if(*this<=1) return *this;
        bign l=0,r=*this,mid;
        while(r-l>1) {
            mid=(l+r)/2;
            if(mid*mid>*this) r=mid;
            else l=mid;
        }
        return l;
    }
};

持续更新中…

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值