zoukankan      html  css  js  c++  java
  • 【Codeforces #1137 F】—Matches Are Not a Child's Play(LCT)

    传送门

    初始设根为nn
    考虑对于每个点
    如果一个子树最大值大于自己,就把向那个子树的边设成重链
    这样每条重链都是连续删除的一段
    设个标号为链底的值
    CompareCompare直接22whenwhen就可以了
    whenwhen只需要查询所有标号小于当前链的和以及链底的一段的sizesize
    而修改一个点之后它到根一定是最后的一段,而且是从原来的根到当前这个点
    makerootmakeroot操作一样

    然后就完了

    #include<bits/stdc++.h>
    using namespace std;
    const int RLEN=1<<20|1;
    inline char gc(){
        static char ibuf[RLEN],*ib,*ob;
        (ob==ib)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
        return (ob==ib)?EOF:*ib++;
    }
    inline int read(){
        char ch=gc();
        int res=0,f=1;
        while(!isdigit(ch))f^=ch=='-',ch=gc();
        while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
        return f?res:-res;
    }
    inline int readchar(char *s){
    	char ch=gc();int top=0;
    	while(!isalpha(ch))ch=gc();
    	while(isalpha(ch))s[top++]=ch,ch=gc();
    	return top;
    }
    #define ll long long
    #define re register
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define pb push_back
    #define cs const
    #define bg begin
    #define poly vector<int>
    inline void chemx(int &a,int b){a<b?a=b:0;}
    inline void chemn(int &a,int b){a>b?a=b:0;}
    cs int N=200005;
    namespace Tr{
    	cs int N=400000;
    	int tr[N+5];
    	#define lb(x) (x&(-x))
    	inline void update(int p,int k){
    		for(;p<=N;p+=lb(p))tr[p]+=k;
    	}
    	inline int query(int p,int res=0){
    		for(;p;p-=lb(p))res+=tr[p];return res;
    	}
    }
    int n,m,val[N],tot;
    vector<int> e[N];
    char s[N];
    namespace Lct{
    	int son[N][2],fa[N],rev[N],siz[N];
    	#define lc(u) son[u][0]
    	#define rc(u) son[u][1]
    	inline bool isrt(int u){
    		return fa[u]?(lc(fa[u])!=u&&rc(fa[u])!=u):1;
    	}
    	inline bool isrc(int u){
    		return rc(fa[u])==u;
    	}
    	inline void pushnow(int u){
    		swap(lc(u),rc(u)),rev[u]^=1;
    	}
    	inline void pushdown(int u){
    		if(lc(u))val[lc(u)]=val[u];
    		if(rc(u))val[rc(u)]=val[u];
    		if(!rev[u])return;
    		if(lc(u))pushnow(lc(u));
    		if(rc(u))pushnow(rc(u));
    		rev[u]=0;
    	}
    	inline void pushup(int u){
    		siz[u]=1;
    		if(lc(u))siz[u]+=siz[lc(u)];
    		if(rc(u))siz[u]+=siz[rc(u)];
    	}
    	inline void rotate(int v){
    		int u=fa[v],z=fa[u];
    		int t=isrc(v);
    		if(!isrt(u))son[z][isrc(u)]=v;
    		fa[v]=z;
    		fa[son[v][t^1]]=u;
    		son[u][t]=son[v][t^1];
    		fa[u]=v,son[v][t^1]=u;
    		pushup(u),pushup(v);
    	}
    	int stk[N],top;
    	inline void splay(int u){
    		stk[top=1]=u;
    		for(int v=u;!isrt(v);v=fa[v])stk[++top]=fa[v];
    		for(int i=top;i;i--)pushdown(stk[i]);
    		while(!isrt(u)){
    			if(!isrt(fa[u]))
    			isrc(u)==isrc(fa[u])?rotate(fa[u]):rotate(u);
    			rotate(u);
    		}
    	}
    	inline void access(int u){
    		for(int v=0;u;v=u,u=fa[u]){
    			splay(u),rc(u)=0,pushup(u);
    			Tr::update(val[u],-siz[u]);
    			Tr::update(tot,siz[u]);
    			rc(u)=v;
    			pushup(u);
    		}
    	}
    	inline void makert(int u){
    		access(u),splay(u),pushnow(u);
    	}
    	inline void update(int u){
    		tot++,makert(u),val[u]=tot;
    	}
    	inline int query(int u){
    		splay(u);
    		return Tr::query(val[u])-siz[lc(u)];
    	}
    }
    void dfs(int u,int fa){
    	int mx=0,son=0;val[u]=u;
    	for(int &v:e[u]){
    		if(v==fa)continue;
    		dfs(v,u);if(val[v]>mx)mx=val[v],son=v;
    		Lct::fa[v]=u;
    	}
    	if(mx>val[u])Lct::rc(u)=son,val[u]=mx;
    	Lct::pushup(u),Tr::update(val[u],1);
    }
    int main(){
    	tot=n=read(),m=read();
    	for(int i=1;i<n;i++){
    		int u=read(),v=read();
    		e[u].pb(v),e[v].pb(u);
    	}
    	dfs(n,0);
    	while(m--){
    		int len=readchar(s),u=read();
    		if(s[0]=='u'){
    			Lct::update(u);
    		}
    		else if(s[0]=='w'){
    			cout<<Lct::query(u)<<'
    ';
    		}
    		else{
    			int v=read();
    			cout<<(Lct::query(u)>Lct::query(v)?v:u)<<'
    ';
    		}
    	}
    }
    
  • 相关阅读:
    python中拆分和拼接字符串
    python中find查找是否包含特定字符并返回第一个索引
    python中删除字符串左右的空格
    python中指定字符串宽度,并指定填充字符串
    python中将字符串中的制表符转换为空格
    python中统计字符串中特定字符出现的次数,内置方法count
    python中指定分隔符分割字符串,返回三元组
    学习笔记:社会科学的特质
    启示——来自《DOOM启世录》
    多语言处理 > UNICODE > IBM的ICU类库
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/12328514.html
Copyright © 2011-2022 走看看