• HNOI2016网络



    加入删除都有

    线段树分治?二进制分组?整体二分?

    线段树分治时间轴建树,询问修改各(nlog)

    但是咋处理询问!?是不经过的最大值

    瞄了眼之前的代码 又作弊!

    竟然是整体二分

    把大于(mid)的加入,若经过的=总共加入的->([l,mid]),否则到右半段

    树状数组即可

    时间复杂度(O(nlog^2n))

    #include<bits/stdc++.h>
    using namespace std;
    inline int read(){
    	int x=0,f=1;char c=getchar();
    	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
    	while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    	return f==1?x:-x;
    }
    const int N=1e5+4;
    struct Ques{int u,v,w;}Q[N<<1];
    struct ques{int u,v,w,t,id;}q[N<<1],q1[N<<1],q2[N<<1];
    int dep[N],siz[N],fa[N],son[N],st[N],ed[N],top[N],tim=0;
    vector<int>e[N];
    int n,m,t[N],ans[N<<1],cnt=0,num=0;
    void dfs_1(int x){
    	dep[x]=dep[fa[x]]+1;
    	siz[x]=1;
    	for(auto v:e[x]){
    		if(v==fa[x])continue;
    		fa[v]=x;
    		dfs_1(v);
    		siz[x]+=siz[v];
    		if(siz[v]>siz[son[x]])son[x]=v;
    	}
    } 
    void dfs_2(int x,int tp){
    	top[x]=tp;
    	st[x]=++tim;
    	if(son[x])dfs_2(son[x],tp);
    	for(auto v:e[x]){
    		if(v==fa[x]||v==son[x])continue;
    		dfs_2(v,v);
    	}
    	ed[x]=tim;
    }
    inline int getlca(int u,int v){
    	while(top[u]!=top[v]){
    		if(dep[top[u]]<dep[top[v]])u^=v^=u^=v;
    		u=fa[top[u]];
    	}
    	return dep[u]<dep[v]?u:v;
    }
    inline void add(int x,int v){
    	if(!x)return;
    	for(;x<=n;x+=x&-x)t[x]+=v;
    }
    inline int ask(int x){
    	int ret=0;
    	for(;x;x-=x&-x)ret+=t[x];
    	return ret;
    }
    void solve(int al,int ar,int ql,int qr){
    	if(ql>qr)return;
    	if(al==ar){
    		if(!ar)ar=-1;
    		for(int i=ql;i<=qr;i++)
    			if(!q[i].id)ans[q[i].w]=ar;
    		return;
    	}
    	int mid=al+ar>>1,cn1=0,cn2=0;
    	for(int i=ql,lca,lei=0,c;i<=qr;i++){
    		if(!q[i].id){
    			if(ask(ed[q[i].u])-ask(st[q[i].u]-1)==lei)q1[++cn1]=q[i];
    			else q2[++cn2]=q[i];
    		}
    		else if(q[i].w>mid){
    			lca=getlca(q[i].u,q[i].v);
    			c=q[i].id;
    			lei+=c;
    			add(st[q[i].u],c);add(st[q[i].v],c);
    			add(st[lca],-c);add(st[fa[lca]],-c);
    			q2[++cn2]=q[i];
    		}
    		else q1[++cn1]=q[i];
    	}
    	for(int i=ql,lca,c;i<=qr;i++)
    		if(q[i].id&&q[i].w>mid){
    			lca=getlca(q[i].u,q[i].v);
    			c=q[i].id;
    			add(st[q[i].u],-c);add(st[q[i].v],-c);
    			add(st[lca],c);add(st[fa[lca]],c);
    		}
    	for(int i=1;i<=cn1;i++)q[ql+i-1]=q1[i];
    	for(int i=1;i<=cn2;i++)q[ql+cn1+i-1]=q2[i];
    	solve(al,mid,ql,ql+cn1-1);solve(mid+1,ar,ql+cn1,qr); 
    }
    int main(){
    	n=read();m=read();
    	for(int i=1,u,v;i<n;i++){
    		u=read();v=read();
    		e[u].push_back(v);e[v].push_back(u);
    	} 
    	dfs_1(1);
    	dfs_2(1,1);
    	for(int i=1,op,u,v,w;i<=m;i++){
    		op=read();u=read();
    		if(op==1)q[++cnt]=(ques){Q[u].u,Q[u].v,Q[u].w,i,-1};
    		else if(op==2)q[++cnt]=(ques){u,0,++num,i,0};
    		else{
    			v=read();w=read();
    			q[++cnt]=(ques){u,v,w,i,1};
    			Q[i]=(Ques){u,v,w}; 
    		}
    	}
    	solve(0,1e9,1,cnt);
    	for(int i=1;i<=num;i++)cout<<ans[i]<<"
    ";
    	return (0-0);
    }
    
  • 相关阅读:
    大话设计模式---单一职责原则
    大话设计模式---策略模式
    计算机网络(二)
    计算机网络(一)
    栈与队列

    数据库面试题——基本概念
    链表
    【Essential c++】——(三)泛型编程风格
    【转载】学习JAVA WEB的路线
  • 原文地址:https://www.cnblogs.com/aurora2004/p/12628804.html
Copyright © 2020-2023  润新知