zoukankan      html  css  js  c++  java
  • bzoj3731: Gty的超级妹子树

    一代神题啊orz(至少是以前年代的神题吧)

    块状树

    复杂度nsqrtnlogn

    真是exciting

    还没有卡时限

    话不多说直接上代码

    (最近解锁了记事本写代码的技能...感觉越来越依赖OJ调试了...啊感觉写代码准确率高了不少qwq)

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <cstdlib>
    #include <algorithm>
    #include <vector>
    #define N 200006
    #define M 400006
    
    using namespace std;
    inline int read(){
    	int ret=0;char ch=getchar();
    	while (ch<'0'||ch>'9') ch=getchar();
    	while ('0'<=ch&&ch<='9'){
    		ret=ret*10-48+ch;
    		ch=getchar();
    	}
    	return ret;
    }
    
    const int KK=400;
    vector<int> seq[N];
    
    struct edge{
    	int adj,next;
    	edge(){}
    	edge(int _adj,int _next):adj(_adj),next(_next){}
    } e[M];
    int n,g[N],m;
    void AddEdge(int u,int v){
    	e[++m]=edge(v,g[u]);g[u]=m;
    	e[++m]=edge(u,g[v]);g[v]=m;
    }
    int w[N];
    
    vector<int> nxt[N];
    int fa[N],bl[N],sz[N],cnt,top[N];
    void refresh(int u,int p){
    	for (;p>0&&seq[u][p]<seq[u][p-1];--p)swap(seq[u][p],seq[u][p-1]);
    	for (;p<sz[u]-1&&seq[u][p]>seq[u][p+1];++p)swap(seq[u][p],seq[u][p+1]);
    }
    void newnode(int u){
    	if (sz[bl[fa[u]]]==KK){
    		sz[bl[u]=++cnt]=0;
    		top[cnt]=u;
    	}
    	else bl[u]=bl[fa[u]];
    	++sz[bl[u]];
    }
    void dfs(int u){
    	newnode(u);
    	for (int i=g[u];i;i=e[i].next){
    		int v=e[i].adj;
    		if (v==fa[u]) continue;
    		fa[v]=u;
    		dfs(v);
    	}
    }
    void dfs_pre(int u){
    	seq[bl[u]].push_back(w[u]);++sz[bl[u]];
    	for (int i=g[u];i;i=e[i].next)if (fa[e[i].adj]==u){
    		int v=e[i].adj;
    		if (bl[v]==bl[u]) dfs_pre(v);
    		else nxt[bl[u]].push_back(bl[v]);
    	}
    }
    void prepare(int id){
    	seq[id].clear();vector<int>(seq[id]).swap(seq[id]);
    	nxt[id].clear();vector<int>(nxt[id]).swap(nxt[id]);
    	sz[id]=0;
    	dfs_pre(top[id]);
    	sort(seq[id].begin(),seq[id].end());
    }
    
    int solve(int u,int lmt){
    	int l=-1,r=sz[u],mid;
    	while (l+1<r){
    		mid=l+r>>1;
    		if (seq[u][mid]<=lmt) l=mid;
    		else r=mid;
    	}
    	int ret=sz[u]-l-1;
    	for (int j=nxt[u].size()-1;j>=0;--j) ret+=solve(nxt[u][j],lmt);
    	return ret;
    }
    int query(int u,int lmt){
    	if (bl[u]!=bl[fa[u]]) return solve(bl[u],lmt);
    	int ret=w[u]>lmt;
    	for (int i=g[u];i;i=e[i].next)if (fa[e[i].adj]==u)ret+=query(e[i].adj,lmt);
    	return ret;
    }
    
    void modify(int u,int x){
    	int p;
    	for (int i=0;i<sz[bl[u]];++i)
    		if (seq[bl[u]][i]==w[u]){p=i;break;}
    	w[u]=x;seq[bl[u]][p]=x;
    	refresh(bl[u],p);
    }
    
    void create(int u,int x){
    	AddEdge(u,++n);fa[n]=u;w[n]=x;
    	int tmp=cnt;
    	newnode(n);
    	seq[bl[n]].push_back(w[n]);
    	refresh(bl[n],sz[bl[n]]-1);
    	if (tmp<cnt) nxt[bl[u]].push_back(cnt);
    }
    
    void dfs_update(int u,int last,int now){
    	bl[u]=now;
    	for (int i=g[u];i;i=e[i].next)if (fa[e[i].adj]==u)
    		if (bl[e[i].adj]==last) dfs_update(e[i].adj,last,now);
    }
    
    void cut(int u){
    	int lst=bl[u];
    	if (bl[fa[u]]!=bl[u]){
    		int f=bl[fa[u]];
    		for (vector<int>::iterator it=nxt[f].begin();it!=nxt[f].end();++it)
    			if ((*it)==lst){nxt[f].erase(it);break;}
    		fa[u]=0;return;
    	}
    	top[++cnt]=u;
    	fa[u]=0;
    	dfs_update(u,lst,cnt);
    	prepare(lst);
    	prepare(cnt);
    }
    
    int main(){
    	n=read();
    	memset(g,0,sizeof(g));m=1;
    	for (int i=1;i<n;++i) AddEdge(read(),read());
    	for (int i=1;i<=n;++i) w[i]=read();
    	fa[1]=0;bl[0]=0;sz[0]=KK;cnt=0;
    	dfs(1);
    	int lastans=0;
    	for (int i=1;i<=cnt;++i) prepare(i);
    	for (int Q=read();Q;Q--){
    		int op=read(),u=read()^lastans,x;
    		if (op<3) x=read()^lastans;
    		else cut(u);
    		if (op==0) printf("%d
    ",lastans=query(u,x));
    		else if (op==1) modify(u,x);
    		else if (op==2) create(u,x);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    linux升级node版本
    mysql视图
    mysql全文本搜索
    mysql数据处理函数
    mysql数据分组
    mysql组合查询
    Django添加生产环境配置
    费用保险单,如何失焦时自动补零
    div+css滚动条
    phpadmin导入数据提示文件最大限制的修改方法
  • 原文地址:https://www.cnblogs.com/wangyurzee7/p/5538448.html
Copyright © 2011-2022 走看看