【POJ】【P3237】【Tree】【题解】【树链剖分+线段树】

传送门:poj.org/problem?id=3237

最近刷数据结构刷上瘾了??天天刷链剖= = 、 (该学学LCT了……)

Code:

#include<cstdio>
#include<cstring>
#include<vector>
#include<iostream>
#include<algorithm>
#include<climits>
#define lson i<<1,l,mid
#define rson i<<1|1,mid+1,r
#define L i<<1
#define R i<<1|1
#define Clear(x) memset(x,0,sizeof(x))
using namespace std;
int n;
const int maxn=10200;
int rw[maxn],vis2[maxn],w[maxn],dep[maxn],vis[maxn],fa[maxn],son[maxn],siz[maxn],top[maxn],z,sor[maxn];
typedef pair<int,int> pii;
pii edges[maxn];
vector<pii>G[maxn];
void add(int u,int v,int w){
	G[u].push_back(pii(v,w));
	G[v].push_back(pii(u,w));
}
int getint(){
	int res=0,ok=0,f=1;char ch;
	while(1){
		ch=getchar();
		if(ch=='-'){f*=-1;continue;}
		if(ch<='9'&&ch>='0'){
			res*=10;res+=ch-'0';ok=1;
		}else if(ok)break;
	}return res*f;
}
struct node{
	int maxx,minn,lazy;
	void init(){
		maxx=INT_MIN,minn=INT_MAX,lazy=0;
	}
};
node t[maxn<<2];
struct seg_tree{
	void pushdown(int i){
		if(!t[i].lazy)return;
		int maxx=t[L].maxx,minn=t[L].minn;
		t[L].maxx=-minn;
		t[L].minn=-maxx;
		t[L].lazy^=1;
		maxx=t[R].maxx;minn=t[R].minn;
		t[R].maxx=-minn;
		t[R].minn=-maxx;
		t[R].lazy^=1;
		
		t[i].lazy^=1;
	}
	void maintain(int i){
//		if(!vis2[L]){
//			vis2[L]=1;t[L].init();
//		}
//		if(!vis2[R]){
//			vis2[R]=1;t[R].init();
//		}
		t[i].maxx=max(t[L].maxx,t[R].maxx);
		t[i].minn=min(t[L].minn,t[R].minn);		
	}
	void Change(int i,int l,int r,int pos,int val){
		if(l==r){
//			if(!vis2[i]){
//				vis2[i]=1;t[i].init();
//			}
			t[i].maxx=t[i].minn=val;t[i].lazy=0;
			return;
		}
//		if(!vis2[i]){
//			vis2[i]=1;t[i].init();
//			vis2[L]=vis2[R]=1;
//			t[L].init();t[R].init();
//		}
		pushdown(i);
		int mid=(l+r)>>1;
		if(pos<=mid)Change(lson,pos,val);
		else Change(rson,pos,val);
		maintain(i);
	}
	void Negate(int i,int l,int r,int l0,int r0){
		if(l0<=l&&r0>=r){
			int maxx=t[i].maxx,minn=t[i].minn;
			t[i].maxx=-minn;
			t[i].minn=-maxx;
			t[i].lazy^=1;
			return;
		}
		pushdown(i);
		int mid=(l+r)>>1;
		if(l0<=mid)Negate(lson,l0,r0);
		if(r0>mid )Negate(rson,l0,r0);
		maintain(i);
	}
	int qmax(int i,int l,int r,int l0,int r0){
		if(l0<=l&&r0>=r){
			return t[i].maxx;
		}
		pushdown(i);
		int mid=(l+r)>>1,ans=INT_MIN;
		if(l0<=mid)ans=max(ans,qmax(lson,l0,r0));
		if(r0>mid) ans=max(ans,qmax(rson,l0,r0));
		return ans;
	}
	void debb(){
		for(int i=1;i<=15;i++)
		cout<<i<<" "<<t[i].maxx<<" "<<t[i].minn<<" "<<t[i].lazy<<endl;

	}
}T;
void dfs(int u){
	son[u]=0;siz[u]=1;
	for(int i=0;i<G[u].size();i++){
		int v=G[u][i].first;
		if(fa[u]!=v){
			dep[v]=dep[u]+1;
			fa[v]=u;
			dfs(v);
			if(siz[son[u]]<siz[v])son[u]=v;
			siz[u]+=siz[v];
		}
	}
}
void Change(int u,int val){
	if(w[u]!=1)
	T.Change(1,1,n,w[u],val);
}
void build(int u,int W,int tp){
	w[u]=++z;Change(u,W);top[u]=tp;
	if(son[u])
	for(int i=0;i<G[u].size();i++)if(G[u][i].first==son[u])build(G[u][i].first,G[u][i].second,tp);
	for(int i=0;i<G[u].size();i++){
		int v=G[u][i].first;
		if(v!=fa[u]&&v!=son[u]){
			build(v,G[u][i].second,v);
		}
	}
}


void Negate(int u,int v){
	while(top[u]!=top[v]){
		if(dep[top[u]]>dep[top[v]]){
			int a=w[u],b=w[top[u]];
			if(a>b)swap(a,b);
			T.Negate(1,1,n,a,b);
			u=fa[top[u]];
		}else{
			int a=w[v],b=w[top[v]];
			if(a>b)swap(a,b);
			T.Negate(1,1,n,a,b);
			v=fa[top[v]];
		}
	}
	int a=w[u],b=w[v];
	if(a>b)
	swap(a,b);
	if(a!=b)
	T.Negate(1,1,n,a+1,b);
}
int qmax(int u,int v){
	int ans=INT_MIN;
	while(top[u]!=top[v]){
		if(dep[top[u]]>dep[top[v]]){
			int a=w[u],b=w[top[u]];
			if(a>b)swap(a,b);
			ans=max(ans,T.qmax(1,1,n,a,b));
			u=fa[top[u]];
		}else{
			int a=w[v],b=w[top[v]];
			if(a>b)swap(a,b);
			ans=max(ans,T.qmax(1,1,n,a,b));
			v=fa[top[v]];
		}
	}
	int a=w[u],b=w[v];
	if(a>b)swap(a,b);
	if(a!=b)
	ans=max(ans,T.qmax(1,1,n,a+1,b));
	return ans;
}
int main(){
	int TT=getint();
	while(TT--){
		Clear(edges);Clear(vis2);Clear(vis);Clear(w);Clear(dep);Clear(fa);Clear(son);Clear(siz);Clear(top);Clear(sor);Clear(t);
		n=getint();z=0;//sor[0]=INT_MIN;
		for(int i=1;i<=n;i++)G[i].clear();
		for(int i=1;i<=(n<<2);i++)t[i].init();
		for(int i=1;i<n;i++){
			int u=getint(),v=getint(),w=getint();add(u,v,w);edges[i].first=u;edges[i].second=v;
		}
		dfs(1);
		build(1,INT_MIN,1);
		//T.debb();
		
		char opt[22];int fuck=0;//n--;
		while(scanf("%s",opt)==1){
			switch(opt[0]){
				case 'D':{
					fuck=1;
					break;
				}
				case 'Q':{
					int u=getint(),v=getint();
					printf("%d\n",qmax(u,v));
					break;
				}
				case 'C':{
					int u=getint(),val=getint();
					if(dep[edges[u].first]>dep[edges[u].second])
						u=edges[u].first;
					else
						u=edges[u].second;
//					T.Change(1,1,n,w[u])
					Change(u,val);
					break;
				}
				case 'N':{
					int u=getint(),v=getint();
					Negate(u,v);
					break;
				}
			}
//			T.debb();
//			cout<<endl;
			if(fuck)break;
		}
	}
	return 0;
}



你可能感兴趣的:(bzoj,省选)