zoukankan      html  css  js  c++  java
  • 我的代码模板库

    我的代码模板库

    目录

    树型结构

    数据结构

    网络流

    数学 数论

    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 
    ",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];
      }
    }
    
  • 相关阅读:
    SQL注入
    mysq笔记
    白话内存管理(一):从开国大典说起
    【转载】光纤协议中 WWPN 编码规则及实例解析
    利用django打造自己的工作流平台(三):任务的批量分派和跟踪
    利用django打造自己的工作流平台(二):疫情统计系统
    利用django打造自己的工作流平台(一):从EXCEL到流程化运作
    驾驭git merge——git merge的规范化操作
    一款用于绘制状态机转换图和流程图的web在线绘图工具
    利用python+graphviz绘制数据结构关系图和指定目录下头文件包含关系图
  • 原文地址:https://www.cnblogs.com/tply/p/8467823.html
Copyright © 2011-2022 走看看