社区讨论

求调树剖

P1505[国家集训队] 旅游参与者 2已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@lo7z0g0c
此快照首次捕获于
2023/10/27 10:04
2 年前
此快照最后确认于
2023/10/27 10:04
2 年前
查看原帖
rt,只过了样例
CPP
#include<bits/stdc++.h>
using namespace std;
const int N=200005;
int head[N],id[N],siz[N],cnt,top[N],fa[N],son[N],wt[N],w[N],a[N],dep[N],n,m,ecnt;
struct edge {
	int next,to,val;
} e[N<<1];
void add(int u,int v,int d) {
	e[++ecnt]= {head[u],v,d};
	head[u]=ecnt;
}
struct node {
	int l,r,sum,maxx,minx,tag;
	node operator +(const node &x)const {
		return {l,x.r,sum+x.sum,max(maxx,x.maxx),min(minx,x.minx),0};
	}
} tree[N<<2];
#define pushup(now) tree[now]=tree[now<<1]+tree[now<<1|1]
void build(int now,int l,int r) {
	if(l==r) {
		tree[now]={l,r,wt[l],wt[l],wt[l],0};
		return ;
	}
	int mid=(l+r)>>1;
	build(now<<1,l,mid);
	build(now<<1|1,mid+1,r);
	pushup(now);
}
void apply(int now,int tag) {
	if(tag==0)
		return ;
	tree[now].sum=-tree[now].sum;
	int Max=tree[now].maxx,Min=tree[now].minx;
	tree[now].maxx=-Min;
	tree[now].minx=-Max;
}
void givetag(int now,int tag) {
	tree[now].tag=tree[now].tag^tag;
	apply(now,tag);
}
void pushdown(int now) {
	if(tree[now].tag==0)
		return ;
	givetag(now<<1,tree[now].tag);
	givetag(now<<1|1,tree[now].tag);
	tree[now].tag=0;
}
void modify1(int now,int l,int r,int v) {
	if(tree[now].l!=tree[now].r)
		pushdown(now);
	if(tree[now].l==l&&tree[now].r==r) {
		tree[now]= {l,r,v,v,v,0};
		return ;
	}
	int mid=(tree[now].l+tree[now].r)>>1;
	if(l<=mid)
		modify1(now<<1,l,r,v);
	if(r>mid)
		modify1(now<<1|1,l,r,v);
	pushup(now);
}
void modify(int now,int l,int r,int v) {
	if(tree[now].l!=tree[now].r)
		pushdown(now);
	if(l<=tree[now].l&&tree[now].r<=r) {
		givetag(now,v);
		return ;
	}
	int mid=(tree[now].l+tree[now].r)>>1;
	if(l<=mid)
		modify(now<<1,l,r,v);
	if(r>mid)
		modify(now<<1|1,l,r,v);
	pushup(now);
}
node query(int now,int l,int r) {
	if(tree[now].l!=tree[now].r)
		pushdown(now);
	if(l<=tree[now].l&&tree[now].r<=r)
		return tree[now];
	int mid=(tree[now].l+tree[now].r)>>1;
	if(l<=mid&&r>mid)
		return tree[now<<1]+tree[now<<1|1];
	if(l<=mid)
		return tree[now<<1];
	if(r>mid)
		return tree[now<<1|1];
}
void dfs1(int x,int father,int deep) {
	dep[x]=deep;
	fa[x]=father;
	siz[x]=1;
	int maxson=-1;
	for(int i=head[x]; i; i=e[i].next) {
		int v=e[i].to;
		if(v==father)
			continue;
		w[v]=e[i].val;
//		cout<<'('<<x<<" "<<v<<" "<<w[x]<<")"<<endl;
		dfs1(v,x,deep+1);
		siz[x]+=siz[v];
		if(siz[v]>maxson) {
			maxson=v;
			son[x]=v;
		}
	}
}
void dfs2(int x,int topf) {
	id[x]=++cnt;
	wt[cnt]=w[x];
//	cout<<"&"<<wt[cnt]<<"&"<<x<<endl;
	top[x]=topf;
	if(!son[x])
		return ;
	dfs2(son[x],topf);
	for(int i=head[x]; i; i=e[i].next) {
		int v=e[i].to;
		if(v==fa[x]||v==son[x])
			continue;
		dfs2(v,v);
	}
}
node qrange(int x,int y) {
	node ans= {0,0,0,-100000,100000,0};
	while(top[x]!=top[y]) {
		if(dep[top[x]]<dep[top[y]])
			swap(x,y);
		ans=ans+query(1,id[top[x]],id[x]);
		x=fa[top[x]];
	}
//	cout<<"["<<x<<" "<<y<<"]"<<endl;
	if(dep[x]>dep[y])
		swap(x,y);
//	cout<<"["<<x<<" "<<y<<"]"<<endl;
//	cout<<id[x]<<" "<<id[y]<<endl;
	ans=ans+query(1,id[x]+1,id[y]);
	return ans;
}
void mrange(int x,int y,int k) {
	while(top[x]!=top[y]) {
		if(dep[top[x]]<dep[top[y]])
			swap(x,y);
		modify(1,id[top[x]],id[x],k);
		x=fa[top[x]];
	}

	if(dep[x]>dep[y])
		swap(x,y);
//	cout<<"["<<x<<" "<<y<<"]"<<endl;
//	cout<<id[x]<<" "<<id[y]<<endl;
	modify(1,id[x]+1,id[y],k);
}
void mrange1(int x,int y,int k) {
	while(top[x]!=top[y]) {
		if(dep[top[x]]<dep[top[y]])
			swap(x,y);
		modify1(1,id[top[x]],id[x],k);
		x=fa[top[x]];
	}
	if(dep[x]>dep[y])
		swap(x,y);
	modify1(1,id[x]+1,id[y],k);
}
pair<int,int> E[N<<1];
int main() {
	cin>>n;
	for(int i=1; i<n; i++) {
		int x,y,z;
		cin>>x>>y>>z;
		E[i].first=x;
		E[i].second=y;
		add(x,y,z);
		add(y,x,z);
	}
	dfs1(0,0,1);
	dfs2(0,0);
	build(1,1,n);
	cin>>m;
	for(int i=1; i<=m; i++) {
		string opt;
		int x,y;
		cin>>opt>>x>>y;
		if(opt=="C")
			mrange1(E[x].first,E[x].second,y);
		if(opt=="N")
			mrange(x,y,1);
		if(opt=="SUM")
			cout<<qrange(x,y).sum<<endl;
		if(opt=="MAX")
			cout<<qrange(x,y).maxx<<endl;
		if(opt=="MIN")
			cout<<qrange(x,y).minx<<endl;
//		cout<<qrange(0,n-1).sum<<" "<<qrange(0,n-1).maxx<<" "<<qrange(0,n-1).minx<<endl;
	}
}

回复

2 条回复,欢迎继续交流。

正在加载回复...