zoukankan      html  css  js  c++  java
  • BZOJ3720: Gty的妹子树

    用“重量平衡树”实现的ETT套平衡树就可以做到$O(nlog^2n)$了。然而我很无聊地写了个$O(nsqrt{nlog n})$的根号重构,就是每$O(sqrt{nlog n})$次修改就用$O(nlog n)$的代价重构函数式trie。

    #include<cstdio>
    #include<vector>
    #define pb push_back
    const int N=60005;
    struct node{
    	node*i,*j;
    	int s;
    }e[N*30];
    node*now,*r[N];
    void ins(int k,node**o){
    	for(int i=29;~i;--i){
    		*++now=**o,*o=now;
    		if(~k>>i&1)o=&(*o)->i;
    		else
    			++(*o)->s,o=&(*o)->j;
    	}
    }
    int ask(int k,node*o){
    	int s=0;
    	for(int i=29;~i;--i)
    		if(k>>i&1)o=o->j;
    		else
    			s+=o->s,o=o->i;
    	return s;
    }
    int ask(int k,int u,int v){
    	return ask(k,r[v])-ask(k,r[u-1]);
    }
    int dfn,p[N],f1[N],f2[N],w[N],f3[N],vis[N];
    std::vector<int>c,t,g[N];
    void dfs(int u){
    	f1[u]=++dfn,r[dfn]=r[dfn-1],ins(w[u],r+dfn);
    	for(int i=0;i<g[u].size();++i){
    		int v=g[u][i];
    		if(v!=p[u])p[v]=u,dfs(v);
    	}
    	f2[u]=dfn;
    }
    int dfs2(int u,int k){
    	int s=w[u]>k;
    	for(int i=0;i<g[u].size();++i){
    		int v=g[u][i];
    		if(v!=p[u])s+=dfs2(v,k);
    	}
    	return s;
    }
    bool jud(int v,int u){
    	return f1[u]<=f1[v]&&f1[v]<=f2[u];
    }
    void reb(){
    	for(int i=0;i<c.size();++i)
    		w[c[i]]=t[i];
    	c.clear();
    	t.clear();
    	dfn=0,now=e,dfs(1);
    }
    int main(){
    	*(*r=e)={e,e};
    	int n,m,o,u,v,s=0;
    	scanf("%d",&n);
    	for(int i=2;i<=n;++i)
    		scanf("%d%d",&u,&v),g[u].pb(v),g[v].pb(u);
    	for(int i=1;i<=n;++i)
    		scanf("%d",w+i);
    	reb();
    	scanf("%d",&m);
    	for(int k=1;k<=m;++k){
    		scanf("%d%d%d",&o,&u,&v),u^=s,v^=s;
    		if(!o){
    			if(c.size()+n-dfn>3000)
    				reb();
    			if(u>dfn)s=dfs2(u,v);
    			else{
    				s=ask(v,f1[u],f2[u]);
    				for(int i=c.size()-1;~i;--i)
    					if(jud(c[i],u)&&k!=vis[c[i]]){
    						vis[c[i]]=k;
    						if(w[c[i]]>v)--s;
    						if(t[i]>v)++s;
    					}
    				for(int i=n;i>dfn;--i)
    					if(jud(f3[i],u))s+=w[i]>v;
    			}
    			printf("%d
    ",s);
    		}
    		if(o==1)
    			if(u>dfn)w[u]=v;
    			else
    				c.pb(u),t.pb(v);
    		if(o==2){
    			++n,p[n]=u,w[n]=v;
    			f3[n]=u>dfn?f3[u]:u;
    			g[u].pb(n);
    			g[n].pb(u);
    		}
    	}
    }
    
  • 相关阅读:
    人工智能应用卷积神经网络对食道癌的诊断结果--笔记
    面向对象设计
    结构化软件测试----白盒测试技术
    内聚与耦合的实例分析
    图书预定系统
    SQL小技巧
    Keras中RNN、LSTM和GRU的参数计算
    Keras+Tensorboard
    Floyd算法
    生成随机整数
  • 原文地址:https://www.cnblogs.com/f321dd/p/8232660.html
Copyright © 2011-2022 走看看