BZOJ 2157 旅游【裸链剖+线段树

80 篇文章 0 订阅
14 篇文章 0 订阅

因为第一次写链剖的时候跳链写的很naive,现在有迷之心理阴影【望天

再加上蠢似我……目测要写4K代码立刻萎了orz

发现竟然比某神犇的杀蚂蚁长到不知道哪里去了……真是23333

当时看到竟然是边权不是点权觉得根本不可做xxx【只能说明智障了啊QuQ

于是果然出了一些奇怪的蠢错orzorz

话说没有删掉调试里的“cout<<endl;"会RE啊【一脸茫然

二话不说把自己又长又慢的代码扔上来【码风有毒不可看【连自己都不想看的代码2333

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#define INF 0x3f3f3f3f
#define MAXN 20057
using namespace std;	int n,m;
struct t1{
	int to,nxt,lth;
}edge[MAXN<<1];	int cnt_edge=0;
int fst[MAXN];
void addedge(int x,int y,int w){
	edge[++cnt_edge].to=y;
	edge[cnt_edge].nxt=fst[x];
	edge[cnt_edge].lth=w;
	fst[x]=cnt_edge;
}

int val[MAXN]; 

int fth[MAXN],siz[MAXN],son[MAXN],top[MAXN],dpt[MAXN];
int id[MAXN];
void dfs1(int now){
	siz[now]=1;
	for(int tmp=fst[now];tmp;tmp=edge[tmp].nxt){
		if(edge[tmp].to==fth[now])	continue;
		
		int ch=edge[tmp].to;
		id[(tmp+1)>>1]=ch,val[ch]=edge[tmp].lth;//想着这里一定要把边权赋值给儿子就把ch敲成了now【真的now敲起来特别顺手
		
		fth[ch]=now;
		dpt[ch]=dpt[now]+1;
		dfs1(ch);
		siz[now]+=siz[ch];
		if(siz[ch]>siz[son[now]])	son[now]=ch;
	}
}
int dfn[MAXN],cnt_dfs=0;
int dfsn[MAXN];

void dfs2(int now,int tp){
	top[now]=tp;
	dfn[now]=++cnt_dfs;
	dfsn[cnt_dfs]=now;
	if(son[now])	dfs2(son[now],tp);
	for(int tmp=fst[now];tmp;tmp=edge[tmp].nxt){
		if(edge[tmp].to==son[now]||edge[tmp].to==fth[now])	continue;
		int ch=edge[tmp].to;
		dfs2(ch,ch);
	}
}
//=========================================
int sum[MAXN<<2],mx[MAXN<<2],mn[MAXN<<2];
int tag[MAXN<<2];

void updata(int now){
	sum[now]=sum[now<<1]+sum[now<<1|1];
	mx[now]=max(mx[now<<1],mx[now<<1|1]);
	mn[now]=min(mn[now<<1],mn[now<<1|1]);
}
void pushdown(int now){
	sum[now<<1]=-sum[now<<1],sum[now<<1|1]=-sum[now<<1|1];
	mx[now<<1]=-mx[now<<1],mn[now<<1]=-mn[now<<1],swap(mn[now<<1],mx[now<<1]);
	mx[now<<1|1]=-mx[now<<1|1],mn[now<<1|1]=-mn[now<<1|1],swap(mx[now<<1|1],mn[now<<1|1]);
	tag[now]=0,tag[now<<1]^=1,tag[now<<1|1]^=1;
}

void build(int now,int l,int r){
	if(l==r)	return sum[now]=mx[now]=mn[now]=val[dfsn[l]],void();
	int mid=(l+r)>>1;
	build(now<<1,l,mid);
	build(now<<1|1,mid+1,r);
	updata(now);
}
void modify1(int now,int l,int r,int ps,int p){
	if(l==r)	return sum[now]=mx[now]=mn[now]=val[dfsn[l]]=p,void();
	if(tag[now])	pushdown(now);
	
	int mid=(l+r)>>1;
	if(ps<=mid)	modify1(now<<1,l,mid,ps,p);
	else	modify1(now<<1|1,mid+1,r,ps,p);
	updata(now);
}
void modify2(int now,int l,int r,int L,int R){
	if(L<=l&&r<=R)	
		return sum[now]=-sum[now],mx[now]=-mx[now],mn[now]=-mn[now],swap(mx[now],mn[now]),tag[now]^=1,void();
	if(tag[now])	pushdown(now);
	
	int mid=(l+r)>>1;
	if(L<=mid)	modify2(now<<1,l,mid,L,R);
	if(mid<R)	modify2(now<<1|1,mid+1,r,L,R);	
	updata(now);
}

struct t2{
	int s,m1,m2;
	t2(){}
	t2(int aa,int bb,int cc):s(aa),m1(bb),m2(cc){}
	t2 operator + (const t2 x){
		return t2(s+x.s,max(m1,x.m1),min(m2,x.m2));
	}
};
t2 inqry(int now,int l,int r,int L,int R){
	if(L<=l&&r<=R)	return t2(sum[now],mx[now],mn[now]);
	if(tag[now])	pushdown(now);
	int mid=(l+r)>>1;
	t2 tmp=t2(0,-INF,INF);
	if(L<=mid)	tmp=inqry(now<<1,l,mid,L,R);
	if(mid<R)	tmp=tmp+inqry(now<<1|1,mid+1,r,L,R);
	return tmp;
}

void work1(int u,int v){
	int d1,d2;
	while(top[u]!=top[v]){
		d1=dpt[top[u]],d2=dpt[top[v]];
		if(d1<d2)	swap(u,v);
		modify2(1,1,n,dfn[top[u]],dfn[u]);
		u=fth[top[u]];	
	}
	d1=dpt[u],d2=dpt[v];
	if(u==v)	return ;
	if(d1<d2)	swap(u,v);
	modify2(1,1,n,dfn[son[v]],dfn[u]);
}

t2 work2(int u,int v){
	t2 rtn=t2(0,-INF,INF);
	int d1,d2;
	while(top[u]!=top[v]){
		d1=dpt[top[u]],d2=dpt[top[v]];
		if(d1<d2)	swap(u,v);
		rtn=rtn+inqry(1,1,n,dfn[top[u]],dfn[u]);
		u=fth[top[u]];	
	}
	d1=dpt[u],d2=dpt[v];
	if(u==v)	return rtn;
	if(d1<d2)	swap(u,v);
	rtn=rtn+inqry(1,1,n,dfn[son[v]],dfn[u]);
	return rtn; 
}

char opt[7];	int u,v;
t2 ans;
int main(){
//	freopen("orz.in","r",stdin);
//	freopen("orz.out","w",stdout);
	scanf("%d",&n);
	int a,b,c;
	for(int i=1;i<n;++i){
		scanf("%d%d%d",&a,&b,&c);
		++a,++b;
		addedge(a,b,c);
		addedge(b,a,c);
	}
	dpt[1]=0,dpt[0]=-1;
	fth[1]=0,top[1]=0;
	dfs1(1);
	dfs2(1,1);
	
	build(1,1,n);
	
	scanf("%d",&m);
	while(m--){
		scanf("%s%d%d",opt,&u,&v);
		if(opt[0]=='C')	modify1(1,1,n,dfn[id[u]],v);
		else{
			++u,++v;
			if(opt[0]=='N')	work1(u,v);
			else{
				ans=work2(u,v);
				if(opt[1]=='U')	printf("%d\n",ans.s);
				if(opt[1]=='A')	printf("%d\n",ans.m1);
				if(opt[1]=='I')	printf("%d\n",ans.m2);//当时为了用bat和样例fc,在这里加了个cout<<endl;交上去竟然是RE【一脸智障
			}
		}
	}

	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值