我的代码模板库

我的代码模板库

目录

树型结构

数据结构

网络流

数学 数论

LCA问题

ST表

字符串

一、准备阶段

1.Getdit配置

#!/bin/sh
dir=$GEDIT_CURRENT_DOCUMENT_DIR
nam=$GEDIT_CURRENT_DOCUMENT_NAME
gnome-terminal --working-directory=$dir -x bash -c "g++ $nam -g -o te;
echo 'DONE';./te;echo;echo 'END';read"

2.开始模板

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#define rg register int
#define ll long long
#define RG register
#define il inline
using namespace std;

il int gi() {
	rg x=0,o=0;RG char ch=getchar();
	while(ch!='-'&&(ch<'0'||'9'<ch)) ch=getchar();
	if(ch=='-') o=1,ch=getchar();
	while('0'<=ch&&ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
	return o?-x:x;
}

int main() {
	
	return 0;
}

二、代码库

树型结构

1.加边函数

struct Edge{ int to,nxt; }e[SZ];
int Ehead[SZ],Ecnt=2;
il void Eadd(rg u,rg v) {
    e[Ecnt]=(Edge){v,Ehead[u]};
    Ehead[u]=Ecnt++;
    e[Ecnt]=(Edge){u,Ehead[v]};
    Ehead[v]=Ecnt++;
}

2.树剖 (树剖+线段树)

 define lson (rt<<1)
 define rson (rt<<1|1)
void dfs1(rg u,rg ff) {
    fa[u]=ff,dep[u]=dep[ff]+1,siz[u]=1;
    for(rg v,i=Ehead[u]; i; i=e[i].nxt) {
        v=e[i].to; if(v==ff) continue;
        dfs1(v,u);
        siz[u]+=siz[v];
        if(siz[v]>siz[son[u]]) son[u]=v;
    }
}
void dfs2(rg u,rg tp) {
    top[u]=tp,id[u]=++cnt,rid[cnt]=u;
    if(!son[u]) return;
    dfs2(son[u],tp);
    for(rg v,i=Ehead[u]; i; i=e[i].nxt) {
        v=e[i].to;
        if(v==fa[u]||v==son[u]) continue;
        dfs2(v,v);		
    }
}
struct Segtree{ int l,r;ll len,sum,mark; }tr[400040];
il void Seg_debug() {
    for(rg i=1;i<=n*3;++i)
     cout<<tr[i].l<<' '<<tr[i].r<<' '<<tr[i].len<<' '<<tr[i].sum<<' '<<tr[i].mark<<endl;
}
il void pushup(rg rt) {
    tr[rt].sum=(tr[lson].sum+tr[rson].sum)%mo;
}
il void pushdown(rg rt) {
    if(tr[rt].mark) {
        ll mark=tr[rt].mark;
        tr[lson].mark+=mark;
        tr[rson].mark+=mark;
        tr[lson].sum=(tr[lson].sum+mark*tr[lson].len)%mo;
        tr[rson].sum=(tr[rson].sum+mark*tr[rson].len)%mo;
        tr[rt].mark=0;
    }
}
void build(rg rt,rg l,rg r) {
    tr[rt].l=l,tr[rt].r=r,tr[rt].len=r-l+1;
    if(l==r) {tr[rt].sum=w[rid[l]]%mo;return;}
    rg mid=l+r>>1;
    build(lson,l,mid);
    build(rson,mid+1,r);
    pushup(rt);
}
void modify(rg rt,rg L,rg R,ll x) {
    rg l=tr[rt].l,r=tr[rt].r;
    if(L<=l&&r<=R) {
        tr[rt].sum=(tr[rt].sum+tr[rt].len*x)%mo;
        tr[rt].mark+=x;
        return;
    }
    pushdown(rt);
    rg mid=l+r>>1;
    if(L<=mid) modify(lson,L,R,x);
    if(R>mid)  modify(rson,L,R,x);
    pushup(rt);
}
ll query(rg rt,rg L,rg R) {
    rg l=tr[rt].l,r=tr[rt].r;
    if(L<=l&&r<=R) return tr[rt].sum;
    pushdown(rt);
    rg mid=l+r>>1;RG ll ret=0;
	if(L<=mid) ret=(ret+query(lson,L,R))%mo;
    if(R>mid)  ret=(ret+query(rson,L,R))%mo;
    return ret;
}
il ll asksum(rg u,rg v) { // 查询 u 到 v 之间的点权和
    RG ll Ans=0;
    while(top[u]!=top[v]) {  // 注意这里是重链顶端深度大的先跳 而不是这个点深度大的先 
        if(dep[top[u]]<dep[top[v]]) swap(u,v);<span id="des">destination</span>
        Ans=(Ans+query(1,id[top[u]],id[u]))%mo;
        u=fa[top[u]];
    }
    if(id[u]>id[v]) swap(u,v);
    Ans=(Ans+query(1,id[u],id[v]))%mo;
    return Ans;
}
il void addsum(rg u,rg v,ll x) { // 给从u到v路径上的点+x
    while(top[u]!=top[v]) {
        if(dep[top[u]]<dep[top[v]]) swap(u,v);
        modify(1,id[top[u]],id[u],x);
        u=fa[top[u]];
    }
    if(id[u]>id[v]) swap(u,v);
    modify(1,id[u],id[v],x);
}
struct Splaytree{ int rev,sum,val,fa,ch[2]; }tr[SZ];
il void pushup(rg x) {
    tr[x].sum=tr[tr[x].ch[0]].sum^tr[tr[x].ch[1]].sum^tr[x].val;
}
il void pushdown(rg x) {
    if(tr[x].rev) {
        swap(tr[x].ch[0],tr[x].ch[1]);
        tr[tr[x].ch[0]].rev^=1;
        tr[tr[x].ch[1]].rev^=1;
        tr[x].rev=0;
    }
}
il bool isroot(rg x) {
    return tr[tr[x].fa].ch[0]!=x && tr[tr[x].fa].ch[1]!=x;
}
il void rotate(rg x) {
    rg y=tr[x].fa,z=tr[y].fa;
    rg k=(tr[y].ch[1]==x);
    if(!isroot(y)) tr[z].ch[y==tr[z].ch[1]]=x;tr[x].fa=z;
    tr[y].ch[k]=tr[x].ch[k^1],tr[tr[x].ch[k^1]].fa=y;
    tr[x].ch[k^1]=y,tr[y].fa=x;
	pushup(y);
}
il void splay(rg x) {
    stk[top=1]=x;
    for(rg i=x; !isroot(i); i=tr[i].fa)	stk[++top]=tr[i].fa;
    for(rg i=top;i;--i) pushdown(stk[i]);
    while(!isroot(x)) {
        rg y=tr[x].fa,z=tr[y].fa;
        if(!isroot(y)) (tr[y].ch[0]==x)^(tr[z].ch[0]==y)?rotate(x):rotate(y);
        rotate(x);
    }
	pushup(x);
}
il void access(rg x) { 
	for(rg y=0; x; y=x,x=tr[x].fa) 
		splay(x),tr[x].ch[1]=y,pushup(x); 
}
il void makeroot(rg x) { 
	access(x),splay(x),tr[x].rev^=1; 
}
il int findroot(rg x) { 
	access(x),splay(x);  
	while(tr[x].ch[0]) x=tr[x].ch[0]; 
	return x;
}
il void split(rg x,rg y) { // 让xy到一条链上并且y在根x在底
	makeroot(x),access(y),splay(y); 
}
il void cut(rg x,rg y) { 
	split(x,y); 
	if(tr[y].ch[0]==x) tr[y].ch[0]=tr[x].fa=0; 
}
il void link(rg x,rg y) {
	makeroot(x),tr[x].fa=y; 
}

数据结构

1.Splay

#define lson tr[x].ch[0]
#define rson tr[x].ch[1]
il void pushup(rg x) {
	tr[x].siz=tr[lson].siz+tr[rson].siz+tr[x].cnt;
}
il void pushdown(rg x) {
	if(tr[x].tag) {
		tr[lson].tag^=1,tr[rson].tag^=1;
		tr[x].tag=0,swap(lson,rson);
	}
}
il void rotate(rg x) {
    rg y=tr[x].fa,z=tr[y].fa;
    rg k=tr[y].ch[1]==x;
    tr[z].ch[tr[z].ch[1]==y]=x,tr[x].fa=z;
    tr[y].ch[k]=tr[x].ch[k^1],tr[tr[x].ch[k^1]].fa=y;
    tr[x].ch[k^1]=y,tr[y].fa=x;
}
il void splay(rg x,rg goal) {
    while(tr[x].fa!=goal) {
        rg y=tr[x].fa,z=tr[y].fa;	
        if(z!=goal)
         (tr[y].ch[0]==x)^(tr[z].ch[0]==y)?rotate(x):rotate(y);
        rotate(x);
    }
    if(!goal) root=x;
}
il int newnode() {
    if(!top) return ++tot;
    return stk[top--];
}
il void insert(rg x) {
    rg u=root,fa=0;
    while(u&&x!=tr[u].val) fa=u,u=tr[u].ch[x>tr[u].val];
    u=newnode();
    if(fa) tr[fa].ch[x>tr[fa].val]=u;
    tr[u]=(Splaytree){fa,{0,0},x};
    splay(u,0);
}
il int k_th(rg x) {
	rg u=root;
	if(tr[u].siz<x) return 0;
	while(666) {
		pushdown(u);
		rg y=tr[u].ch[0];
		if(x>tr[y].siz+tr[u].cnt) {
			x-=tr[y].siz+tr[u].cnt;
			u=tr[u].ch[1];
		}
		else if(x<=tr[y].siz) u=y;
		else return tr[u].val;
	}
}
il void find(rg x) {
    rg u=root; if(!u) return;
    while(tr[u].ch[x>tr[u].val]&&x!=tr[u].val) u=tr[u].ch[x>tr[u].val];	
    splay(u,0);
}
il int getnext(rg x,rg type) {  // 前驱后继 - 不严格
    find(x);
    if(tr[root].val<=x&&!type) return root;
    if(tr[root].val>=x&&type)  return root;
    rg u=tr[root].ch[type];
    while(tr[u].ch[type^1]) u=tr[u].ch[type^1];
    return u;
}
il int delnext(rg x,rg type) {  // 前驱后继 - 严格
    if(tr[root].val<x&&!type) return root;
    if(tr[root].val>x&&type)  return root;
    rg u=tr[root].ch[type];
    while(tr[u].ch[type^1])
     u=tr[u].ch[type^1];
    return u;
}
il void del(rg x) {
    find(x);
    rg lnum=delnext(x,0);
    rg rnum=delnext(x,1);
    splay(lnum,0),splay(rnum,lnum);
    stk[++top]=tr[rnum].ch[0];
    tr[rnum].ch[0]=0;
}

2.主席树

struct Tree {
	int l,r,sum;
}tr[SZ*25];
#define lson tr[rt].l
#define rson tr[rt].r
int tot,Ed[SZ];
il void Chair_debug() {
	for(rg i=1;i<=tot;++i)
		printf("%d %d %d \n",tr[i].l,tr[i].r,tr[i].sum);
}
il void build(int &rt,rg l,rg r) { //用 & 是为了方便改左右儿子
	rt=++tot;
	if(l==r) return;
	rg mid=l+r>>1;
	build(lson,l,mid);
	build(rson,mid+1,r);
}
il void update(int &rt,rg last,rg l,rg r,rg val) {
	rt=++tot;
	lson=tr[last].l;rson=tr[last].r;
	tr[rt].sum=tr[last].sum+1; // 加1是因为 沿路单点修改 出现次数肯定是 +1
	if(l==r) return;
	rg mid=l+r>>1;
	if(val<=mid) update(lson,tr[last].l,l,mid,val); // 要加等号!!!
	else update(rson,tr[last].r,mid+1,r,val);
	// 相当于 除了新加进来的数,其他的部分都共用  
}

il int query(rg to,rg from,rg l,rg r,rg k) {
	if(l==r) return l;
	rg num=tr[tr[to].l].sum-tr[tr[from].l].sum;
	rg mid=l+r>>1;
	if(k<=num) return query(tr[to].l,tr[from].l,l,mid,k);
	else return query(tr[to].r,tr[from].r,mid+1,r,k-num);
}
// 主席树 Ed[i] 存1到i前缀所建线段树的根
// 每颗线段树的节点作用不同于普通的线段树
// 它保存的是 一个数的出现次数
// 注意这个数是已经排好了序的

3.左偏树

#define lson ch[x][0]
#define rson ch[x][1]
int ch[SZ][2],val[SZ],dis[SZ];
int merge(rg x,rg y) {
    if(!x||!y) return x+y;
    if(val[x]>val[y]||(val[x]==val[y]&&x>y)) swap(x,y);
    rson=merge(rson,y);fa[rson]=x;
    if(dis[lson]<dis[rson]) swap(lson,rson);
    dis[x]=dis[rson]+1;
    return x;
}

网络流

1.最大流

Ecnt=2 // 这里要特别说明 , 因为边的初始标号一定要是2
int lev[SZ],cur[SZ];
queue <int> Q;
il bool bfs() {
    for(rg i=1;i<=n+1;++i) lev[i]=-1;
    while(!Q.empty()) Q.pop();
    Q.push(s);lev[s]=0;
    while(!Q.empty()) {
        rg u=Q.front();Q.pop();
        for(rg i=Ehead[u]; i; i=e[i].nxt)
         if(e[i].w>0&&lev[e[i].to]<0) {
         	lev[e[i].to]=lev[u]+1;
         	Q.push(e[i].to);
         }
    }
    if(lev[t]>0) return 1;
    return 0;
}
int dfs(int u,int f) {
    if(u==t||f==0) return f;
    for(int i=Ehead[u];i;i=e[i].nxt) {
        rg di=0,v=e[i].to;
        if(lev[v]==lev[u]+1 && e[i].w>0)
         if(di=dfs(v,min(f,e[i].w))) {
         	e[i].w-=di;
         	e[i^1].w+=di;
         	return di;
         }
    }
    return 0;
}
il int Dinic() {
    int Ans=0,di;
    while(bfs()) while((di=dfs(s,INF))&&(Ans+=di));
}

2.费用流

// pv流的上一个点
// pe是连接u和pv的边
bool spfa() {
    memset(dis,63,sizeof(dis));
    dis[s]=0;Q.push(s);
    while (!Q.empty()) {
        int u=Q.front();Q.pop();
        for (int v,i=Ehead[u]; i; i=e[i].nxt) {
            v=e[i].to;
            if(e[i].w && dis[v]>dis[u]+e[i].cost) {
                dis[v]=dis[u]+e[i].cost,pe[v]=e,pv[v]=u;
                if (!vis[v]) vis[v]=1,Q.push(v);
            }
        }
        vis[u]=0;
    }
    return dis[t]<dis[0];
}
int main() {
    while (spfa()) {
        int sum=inf;
        for (int i=t;i!=s;i=pv[i]) sum=min(sum,e[pe[i]].w);
        flow+=sum;
        for (int i=t;i!=s;i=pv[i]) e[pe[i]].w-=sum,e[pe[i]^1].w+=sum,ans+=sum*e[pe[i]].cost;
    }
}

3.匈牙利算法

il int hung()
{
	rg Ans=0;
	memset(vis,-1,sizeof(vis));
	memset(mat,-1,sizeof(mat));
	for(rg i=1;i<=n;++i){
		if(mat[i]!=-1) continue;
		while(!Q.empty()) Q.pop();
		Q.push(i),pre[i]=-1,flg=0;
		while(!Q.empty() && !flg) {
			rg u=Q.front();Q.pop();
			for(rg j=Ehead[u];(j)&&(!flg);j=e[j].nxt) {
				rg v=e[j].to;
				if(vis[v]==i) continue; 
				vis[v]=i;
				if(mat[v]>=0)  pre[mat[v]]=u,Q.push(mat[v]);
				else {
					flg=1;
					rg a=u,b=v;
					while(a!=-1) {
						rg c=mat[a];
						mat[a]=b;
						mat[b]=a;
						a=pre[a];
						b=c;
					}
				}
			}
		}
		if(mat[i]!=-1) Ans++; 
	}
	return Ans;    
}

数学 数论

1.高斯消元

il void Gauss() {
    for(rg i=1; i<=n; ++i) {
        now=i;
        for(rg j=i+1; j<=n; ++j)
            if(fabs(f[now][i])<fabs(f[j][i]))
                now=j;
        for(rg j=i; j<=n+1; ++j)
            swap(f[now][j],f[i][j]);
        if(!f[i][i]){puts("No Solution");exit(0);}
        for(rg j=i+1; j<=n+1; ++j) f[i][j]/=f[i][i];
        f[i][i]=1.0;
        for(rg j=i+1; j<=n; ++j) {
            for(rg k=i+1; k<=n+1; ++k)
                f[j][k]-=f[j][i]*f[i][k]; // 理解!
            f[j][i]=0.0;
        }
    }
    for(rg i=n; i>=1; --i) {
        for(rg j=i+1; j<=n; ++j) {
            f[i][n+1]-=f[i][j]*f[j][n+1];
            f[i][j]=0;
        }
        f[i][n+1]/=f[i][i];
        f[i][i]=1;
    }	
}

2.FFT

struct Complex {
    ldb r,i;
    Complex(){} Complex(ldb a,ldb b):r(a),i(b){}
    il Complex operator+(const Complex B)const {return Complex(r+B.r,i+B.i);}
    il Complex operator-(const Complex B)const {return Complex(r-B.r,i-B.i);}
    il Complex operator*(const Complex B)const {return Complex(r*B.r-i*B.i,r*B.i+i*B.r);}
};
Complex X,Y,a[SZ],b[SZ];
il void FFT(Complex *a,int x) {
    for(rg i=0; i<n; ++i) if(i<r[i]) swap(a[i],a[r[i]]);
    for(rg i=1; i<n; i<<=1) {
       Complex wn=(Cos(pi/i),x*sin(pi/i));
        for(rg j=0; j<n; j+=(i<<1)) {
            Complex w(1,0);
            for(rg k=0;k<i;++k,w=w*wn) {
                X=a[j+k],Y=a[i+j+k]*w;
                a[j+k]=X+Y,a[i+j+k]=X-Y;
            }
        }
    }
    if(x==-1) for(rg i=0; i<n; ++i) a[i].r=a[i].r/n;
}
int main() {
    m+=n;for(n=1;n<=m;n<<=1) ++l;
    for(rg i=0;i<n;++i) r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
    FFT(a,1);FFT(b,1);
    for(rg i=0;i<=n;++i) a[i]=a[i]*b[i];
    FFT(a,-1);
    for(rg i=0;i<=m;++i) printf("%d ",(int)(a[i].r+0.5));
}

3.扩展欧几里德

int exgcd(int a,int b,int &x,int &y) {
    if(!b){x=1,y=0;}
    else{exgcd(b,a%b,y,x);y-=a/b*x;}
}
il int inv() {
    exgcd(a,b,x,y);
    return (x+b)%b;
}

LCA问题

1.RMQ+LCA

int par[SZ][50],dep[SZ];
void dfs(int u,int fa) {
    dep[u]=dep[fa]+1;
    par[u][0]=fa;
    for(rg i=1;i<=20;i++) par[u][i]=par[par[u][i-1]][i-1];
    for(rg i=Ehead[u];i;i=e[i].nxt) if(e[i].to!=fa) dfs(e[i].to,u);
}

il int LCA_RMQ(int u,int v) {
    if(dep[u]>dep[v]) swap(u,v);
    for(rg i=0;i<=20;++i)
    	if(((dep[v]-dep[u])>>i)&1)
      		v=par[v][i];
    if(u==v) return u;
    for(rg i=20;i>=0;--i)
    	if(par[u][i]!=par[v][i])
    	{
    	 	u=par[u][i];
    	 	v=par[v][i];
    	}
    return par[u][0];	
}

2.tarjan+LCA

int vis[SZ];
inline void tarjan(int u)
{
    vis[u]=1;
    for(int i=Ehead[u];i;i=e[i].nxt) {
        int v=e[i].to;
        if(vis[v]) continue;
        tarjan(v);
        Union(u,v); 
    }
    for(int i=Qhead[u];i;i=q[i].nxt)
    	if(vis[q[i].to]==2) {
        	q[i].ans=find_fa(q[i].to);
        	if(i&1) q[i+1].ans=q[i].ans;
        	else    q[i-1].ans=q[i].ans;		
     	}
    vis[u]=2; 
}

ST表

il void pre() {
  for(rg j=1;(1<<j)<=n;++j)
  	for(rg i=1;i+(1<<j)-1<=n;++i)
  		R[i][j]=max(R[i][j-1],R[i+(1<<(j-1))][j-1]);
}
il int ask() {
  rg k=log2(r-l+1);
  return max(R[l][k],R[r-(1<<k)+1][k]);
}

字符串

1.AC 自动机

il void init(rg x) {
    memset(tr[x].ch,0,sizeof(tr[x].ch));
    tr[x].fail=tr[x].end=0;
}
il void build(string s,rg Num) {
    rg l=s.length(),now=0;
    for(rg i=0;i<l;++i) {
        if(!tr[now].ch[s[i]-'a']) {
            tr[now].ch[s[i]-'a']=++cnt;
            init(cnt);
        }
        now=tr[now].ch[s[i]-'a'];
    }
    tr[now].end=Num;
}
queue <int> Q;
il void getfail() {
    tr[0].fail=0;
    while(!Q.empty()) Q.pop();
    for(rg i=0;i<26;++i) 
        if(tr[0].ch[i]) {
            tr[tr[0].ch[i]].fail=0;
            Q.push(tr[0].ch[i]);
        }
    while(!Q.empty()) {
        rg u=Q.front();Q.pop();
        for(rg i=0;i<26;++i) {
            if(tr[u].ch[i]) {
                tr[tr[u].ch[i]].fail=tr[tr[u].fail].ch[i];
                Q.push(tr[u].ch[i]);
            }
            else tr[u].ch[i]=tr[tr[u].fail].ch[i];
        }
    }
}
il void query() {
    cin>>s[0];
    rg l=s[0].length(),now=0,fa;
    for(rg i=0;i<l;++i) {
        now=tr[now].ch[s[0][i]-'a'];fa=-1;
        for(rg j=now;j;fa=j,j=tr[j].fail) {
            if(!tr[j].end&&fa!=-1) tr[fa].fail=tr[j].fail;
            ++ans[tr[j].end].num;
        }
    }
}

2.KMP

il void Get_Next() {
	rg i=0,j=-1;nxt[0]=-1;
    while(i<s2.size()) {
    	if(j==-1||s2[i]==s2[j]) nxt[++i]=++j;
    	else j=nxt[j];
    }
}
il void KMP() {
    rg i=0,j=0;
    while(i<s1.size()) {
    	if(j==-1||s1[i]==s2[j]) ++i,++j;
    	else j=nxt[j];
    	if(j==s2.size()) j=nxt[j];
  }
}
posted @ 2018-02-24 22:02  TPLY  阅读(142)  评论(0编辑  收藏  举报