zoukankan      html  css  js  c++  java
  • 省选模板复习—【数据结构】

    树状数组


    线段树


    平衡树

    fhqtreapfhq-treap

    inline int newnode(int k){
    	int u=++tot;key[tot]=rnd(),val[tot]=k;
    	siz[tot]=1;return tot;
    }
    inline void pushup(int u){
    	siz[u]=siz[lc(u)]+siz[rc(u)]+1;
    }
    inline void split(int u,int &r1,int &r2,int k){
    	if(!u){r1=r2=0;return;}
    	if(val[u]<=k){//这是<= 
    		r1=u;split(rc(u),rc(r1),r2,k);
    	}
    	else r2=u,split(lc(u),r1,lc(r2),k);
    	pushup(u);
    }
    inline void merge(int &u,int r1,int r2){
    	if(!r1||!r2){u=r1+r2;return;}
    	if(key[r1]<key[r2]){
    		u=r1,merge(rc(u),rc(r1),r2);
    	}
    	else u=r2,merge(lc(u),r1,lc(r2));
    	pushup(u);
    }
    inline int find(int u,int k){
    	while(siz[lc(u)]+1!=k){
    		if(siz[lc(u)]>=k)
    			u=lc(u);
    		else k-=siz[u]-siz[rc(u)],u=rc(u);
    	}
    	return u;
    }
    inline void insert(int k){
    	int u=newnode(k),r1,r2;
    	split(rt,r1,r2,k);
    	merge(r1,r1,u);
    	merge(rt,r1,r2);
    }
    inline void delet(int k){
    	int r1,r2,r3;
    	split(rt,r1,r2,k-1);
    	split(r2,r2,r3,k);
    	merge(r2,lc(r2),rc(r2));
    	merge(r1,r1,r2);
    	merge(rt,r1,r3);
    }
    inline int rank(int k){
    	int r1,r2;
    	split(rt,r1,r2,k-1);
    	int res=siz[r1]+1;
    	merge(rt,r1,r2);
    	return res;
    }
    inline int getval(int k){
    	return val[find(rt,k)];
    }
    inline int pre(int k){
    	int r1,r2;
    	split(rt,r1,r2,k-1);
    	int u=find(r1,siz[r1]);
    	merge(rt,r1,r2);
    	return val[u];
    }
    inline int nxt(int k){
    	int r1,r2;
    	split(rt,r1,r2,k);
    	int u=find(r2,1);
    	merge(rt,r1,r2);
    	return val[u];
    }
    

    LCT

    inline bool isrc(int u){
    	return rc(fa[u])==u;
    }
    inline bool isrt(int u){
    	if(!fa[u])return 1;
    	return lc(fa[u])!=u&&rc(fa[u])!=u;
    }
    inline void pushup(int u){
    	val[u]=a[u];
    	if(lc(u))val[u]+=val[lc(u)];
    	if(rc(u))val[u]+=val[rc(u)];
    }
    inline void pushdown(int u){
    	if(!rev[u])return;
    	swap(lc(u),rc(u));		
    	if(lc(u))rev[lc(u)]^=1;
    	if(rc(u))rev[rc(u)]^=1;
    	rev[u]=0;
    }
    inline void rotate(int v){
    	int u=fa[v],z=fa[u];
    	int t=rc(u)==v;
    	if(!isrt(u))son[z][rc(z)==u]=v;//判断 
    	fa[v]=z;
    	son[u][t]=son[v][t^1],fa[son[v][t^1]]=u;
    	son[v][t^1]=u,fa[u]=v;
    	pushup(u),pushup(v);//顺序 
    }
    inline void splay(int u){
    	q[q[0]=1]=u;
    	for(int v=u;!isrt(v);v=fa[v])q[++q[0]]=fa[v];
    	for(int i=q[0];i;i--)pushdown(q[i]);//先pushdown 
    	while(!isrt(u)){
    		if(!isrt(fa[u])){
    			if(isrc(u)==isrc(fa[u]))rotate(fa[u]);
    			else rotate(u);
    		}
    		rotate(u);
    	}
    	pushup(u);
    }
    inline void access(int u){
    	for(int v=0;u;v=u,u=fa[u]){
    		splay(u),rc(u)=v;
    		if(v)fa[v]=u;
    		pushup(u);
    	}
    }
    inline int findrt(int u){
    	access(u),splay(u);
    	while(pushdown(u),lc(u))u=lc(u);//pushdown
    	splay(u);return u;
    }
    inline void makert(int u){
    	access(u),splay(u),rev[u]^=1;
    }
    inline void link(int u,int v){
    	makert(u),fa[u]=v;
    }
    inline void cut(int u,int v){
    	makert(u),access(v),splay(v);
    	lc(v)=fa[u]=0,pushup(v);
    }
    inline int query(int u,int v){
    	makert(u),access(v),splay(v);return val[v];
    }
    

    维护子树

    multiset<int>chain[N];//注意是multiset
    inline int fir(int u){
    	return chain[u].size()?*chain[u].rbegin():-inf;
    }
    inline void access(int u){
    	for(int v=0;u;v=u,u=fa[u]){
    		splay(u);
    		if(rc(u))chain[u].insert(lmx[rc(u)]);
    		if(v)chain[u].erase(chain[u].find(lmx[v]));
    		rc(u)=v;
    		pushup(u);
    	}
    }
    

    STST表求LcaLca(四倍空间)
    注意二维哪一维在前(二维寻址常数优化(13大约frac 1 3))

    void dfs(int u,int fa){
    	st[0][++dfn]=u;pos[u]=dfn;
    	for(int e=adj[u];e;e=nxt[e]){
    		int v=to[e];
    		if(v==fa)continue;
    		dep[v]=dep[u]+1;
    		dfs(v,u),st[0][++dfn]=u;
    	}
    }
    void init(){
    	dfs(1,0);lg[0]=-1;
    	for(int i=1;i<=dfn;i++)lg[i]=lg[i>>1]+1;
    	for(int i=1;(1<<i)<=dfn;i++){
    		for(int j=1;j+(1<<i)-1<=dfn;j++){
    			int x1=st[i-1][j],x2=st[i-1][j+(1<<(i-1))];
    			st[i][j]=dep[x1]>dep[x2]?x2:x1;
    		}
    	}
    }
    inline int ask(int u,int v){
    	int x=pos[u],y=pos[v];
    	if(x>y)swap(x,y);
    	int t=lg[y-x+1];
    	int x1=st[t][x],x2=st[t][y-(1<<t)+1];
    	return dep[x1]>dep[x2]?x2:x1;
    }
    
    void dfs(int u,int f){
        st[0][++dfn]=dis[u],pos[u]=dfn;
        for(int e=adj[u];e;e=nxt[e]){
            int v=to[e];
            if(v==f)continue;
            dis[v]=dis[u]+1;
            dfs(v,u);
            st[0][++dfn]=dis[u];
        }
    }
    inline void init(){
        dfs(1,0),lg[0]=-1;
        for(int i=1;i<=dfn;i++)lg[i]=lg[i>>1]+1;
        for(int i=1;(1<<i)<=dfn;i++){
            for(int j=1;j+(1<<i)-1<=dfn;j++){
                st[i][j]=min(st[i-1][j],st[i-1][j+(1<<(i-1))]);
            }
        }
    }
    inline int dist(int u,int v){
        int x=pos[u],y=pos[v];
        if(x>y)swap(x,y);
        int t=lg[y-x+1];
        return dis[u]+dis[v]-2*min(st[t][x],st[t][y-(1<<t)+1]);
    }
    

    长剖

    (注意dep[v]dep[v]的范围以及边界(最好每次多开大点但相应数组就要开nmoren*more))

    int *f[N],tmp[N],*id=tmp;
    void dfs1(int u,int fa){
    	for(int e=adj[u];e;e=nxt[e]){
    		int v=to[e];
    		if(v==fa)continue;
    		dfs1(v,u);
    		if(dep[v]>dep[son[u]])son[u]=v;
    	}
    	dep[u]=dep[son[u]]+1;
    }
    void dfs2(int u,int fa){
    	if(son[u]){f[son[u]]=f[u]+1,dfs2(son[u],u);}
    	for(int e=adj[u];e;e=nxt[e]){
    		int v=to[e];
    		if(v==fa||v==son[u])continue;
    		f[v]=id,id+=dep[v],dfs2(v,u);
    		for(int i=0;i<dep[v];i++)calc....;
    	}
    }
    int main(){
    	dfs1(1,0);
    	f[1]=id,id+=dep[1];
    	dfs2(1,0);
    }
    

    虚树

    (注意clearclear

    inline void solve(){
    	stk[top=1]=a[1];
    	for(int i=2;i<=num;i++){
    		int lca=Lca(stk[top],a[i]);
    		while(dfn[lca]<dfn[stk[top]]){
    			if(dfn[lca]>=dfn[stk[top-1]]){
    				G2.addedge(lca,stk[top--]);
    				if(stk[top]!=lca)stk[++top]=lca;
    				break;
    			}
    			G2.addedge(stk[top-1],stk[top]),top--;
    		}
    		stk[++top]=a[i];
    	}
    	while(top>1)G2.addedge(stk[top-1],stk[top]),top--;
    	solve(),clear();
    }
    

    倍增求lcalca注意dep[1]=1dep[1]=1


    动态点分治:

    inline int query(int u,int k){
        int res=0;
        for(int i=u;i;i=fa[i]){
            res+=f1[i].query(k-dist(i,u));
        }
        for(int i=u;fa[i];i=fa[i]){
            res-=f2[i].query(k-dist(fa[i],u));
        }
        return res;
    }
    

    注意计算distdist一个是和当前centercenter一个是和fafa
    一个是判当前有没有一个是父亲有没有

    细节:son[0],maxn,dep[v]=val[e]son[0],maxn,dep[v]=val[e]……


    Kruscal重构树

    重构树要开2倍空间
    dfs(tot)dfs(tot)
    unule n

    (ReturnReturn)

    struct edge{
    	int u,v,w;
    	friend inline bool operator <(const edge &a,const edge &b){
    		return a.w>b.w;
    	}
    }e[N];
    int tot,lc[N],rc[N],fa[N],f[N][22],val[N],g[N];//2倍空间 
    inline int find(int x){
    	return fa[x]==x?fa[x]:fa[x]=find(fa[x]);
    }
    void dfs(int u){
    	for(int i=1;i<=20;i++)f[u][i]=f[f[u][i-1]][i-1];
    	if(u<=n){//
    		g[u]=dis[u];return;
    	}
    	dfs(lc[u]),dfs(rc[u]),g[u]=min(g[lc[u]],g[rc[u]]);
    }
    inline void kruscal(){
    	sort(e+1,e+m+1);
    	for(int i=1,cnt=0;i<=m&&cnt<n-1;i++){
    		int f1=find(e[i].u),f2=find(e[i].v);
    		if(f1!=f2){
    			fa[f1]=fa[f2]=fa[++tot]=tot;
    			val[tot]=e[i].w;
    			lc[tot]=f1,rc[tot]=f2;
    			f[f1][0]=f[f2][0]=tot;cnt++;
    		}
    	}
    	dfs(tot);
    }
    int get(int u,int p){
    	for(int i=20;~i;i--){
    		if(fa[u][i]&&val[f[u][i]]>p)u=f[u][i];//神tm高速缓存优化三维寻址 
    	}
    	return g[u];
    }
    
  • 相关阅读:
    net core 2 读取appsettings.json
    转: C# 根据当前时间获取,本周,本月,本季度等时间段 .Net中Exception
    转:5种回到顶部的写法从实现到增强
    转:jQuery 常见操作实现方式
    NLog 自定义字段 写入 oracle
    转:C# 使用NLog记录日志
    转:NLog之:文件类型目标(File target)
    springboot2.x+jwt+shiro最简单、最快速整合方式
    windows部署mindoc
    docker安装mongodb
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/11145558.html
Copyright © 2011-2022 走看看