P1505 [国家集训队]旅游(树剖板题)

Posted Harris-H

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P1505 [国家集训队]旅游(树剖板题)相关的知识,希望对你有一定的参考价值。

P1505 [国家集训队]旅游(树剖板题)

1.边权转点权。

dfs时边下放到点就行了,因为每个点的父边唯一。

2.然后就是裸的线段树了,区间翻转,区间最值,单点修改,没了。

3.码农题好想吐槽啊。

// Problem: P1505 [国家集训队]旅游
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P1505
// Memory Limit: 256 MB
// Time Limit: 1000 ms
// Date: 2021-08-18 11:54:24
// --------by Herio--------

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull; 
const int N=2e5+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define fi first
#define se second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define ios ios::sync_with_stdio(false),cin.tie(0) 
void Print(int *a,int n){
	for(int i=1;i<n;i++)
		printf("%d ",a[i]);
	printf("%d\\n",a[n]); 
}
//区间修改 区间求和
#define il inline 
#define lx x<<1
#define rx x<<1|1
#define len(x) (a[x].r-a[x].l+1)
int w[N];
struct node{
	int l,r,lz;
	int s,mx,mn;
}a[N<<2];
il void re(int x){
	a[x].s=a[lx].s+a[rx].s;
	a[x].mx=max(a[lx].mx,a[rx].mx);
	a[x].mn=min(a[lx].mn,a[rx].mn);
}
il void ptg(int x){
	a[x].lz^=1;
	a[x].s=-a[x].s,a[x].mx=-a[x].mx,a[x].mn=-a[x].mn;
	swap(a[x].mx,a[x].mn);
}
il void pd(int x){
	if(a[x].lz){
		ptg(lx),ptg(rx);
		a[x].lz=0;
	}
}
il void bud(int x,int l,int r){
	a[x].l=l,a[x].r=r;
	if(l==r){
		a[x].s=a[x].mx=a[x].mn=w[l];
		return;
	}
	int m=(l+r)>>1;bud(lx,l,m),bud(rx,m+1,r);
	re(x);
}
il void upd(int x,int l,int r){
	if(a[x].l>=l&&a[x].r<=r){
		ptg(x);return;
	}
	pd(x);
	int m=(a[x].l+a[x].r)>>1;
	if(l<=m) upd(lx,l,r);
	if(r>m) upd(rx,l,r);
	re(x);
}
il void update(int x,int p,int v){
	//printf("%d %d %d\\n",x,p,v);
	if(a[x].l==a[x].r){
		a[x].mx=a[x].mn=a[x].s=v;return;
	}
	pd(x);
	int m=(a[x].l+a[x].r)>>1;
	if(p<=m) update(lx,p,v);
	else update(rx,p,v);
	re(x);	
}
il int que(int x,int l,int r){
	if(a[x].l>=l&&a[x].r<=r) return a[x].s;
	pd(x);
	int m=(a[x].l+a[x].r)>>1;int ans=0;
	if(l<=m) ans+=que(lx,l,r);
	if(r>m) ans+=que(rx,l,r);
	return ans;
}
il int quemx(int x,int l,int r){
	if(a[x].l>=l&&a[x].r<=r) return a[x].mx;
	pd(x);
	int m=(a[x].l+a[x].r)>>1;int ans=-inf;
	if(l<=m) ans=max(ans,quemx(lx,l,r));
	if(r>m) ans=max(ans,quemx(rx,l,r));
	return ans;
}
il int quemn(int x,int l,int r){
	if(a[x].l>=l&&a[x].r<=r) return a[x].mn;
	pd(x);
	int m=(a[x].l+a[x].r)>>1;int ans=inf;
	if(l<=m) ans=min(ans,quemn(lx,l,r));
	if(r>m)  ans=min(ans,quemn(rx,l,r));
	return ans;
}
//树剖
struct edge{
	int to,nt,w;
}e[N<<1];
int h[N],cnt=1;
void add(int u,int v,int w){
	e[++cnt]={v,h[u],w},h[u]=cnt;
	e[++cnt]={u,h[v],w},h[v]=cnt;
}
int sz[N],fa[N],son[N],top[N],dfn[N],dep[N];
int ys[N];
void dfs(int u,int f){
	sz[u]=1,fa[u]=f,dep[u]=dep[f]+1;
	for(int i=h[u];i;i=e[i].nt){
		int v=e[i].to;
		if(v==f) continue;
		dfs(v,u);
		ys[v]=e[i].w;
		sz[u]+=sz[v];
		if(sz[son[u]]<sz[v]) son[u]=v;
	}
}
int id;
void dfs1(int u,int tp){
	top[u]=tp,dfn[u]=++id;w[id]=ys[u];
	if(son[u]) dfs1(son[u],tp);
	for(int i=h[u];i;i=e[i].nt){
		int v=e[i].to;
		if(v!=fa[u]&&v!=son[u]) dfs1(v,v);
	}
}
int upd_c(int x,int y){	//chain update
	 while(top[x]!=top[y]){
	 	if(dep[top[x]]<dep[top[y]]) swap(x,y);
	 	upd(1,dfn[top[x]],dfn[x]);
	 	x=fa[top[x]];
	 }
	 if(dep[x]<dep[y]) swap(x,y);
	 if(y!=x) upd(1,dfn[y]+1,dfn[x]);
}
int que_cs(int x,int y){		//chain query
	int ans=0;
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
	 	ans=ans+que(1,dfn[top[x]],dfn[x]);
	 	x=fa[top[x]];
	 }
	 if(dep[x]<dep[y]) swap(x,y);
	if(y!=x) ans=ans+que(1,dfn[y]+1,dfn[x]);
	 return ans;
}
int que_cmn(int x,int y){		//chain query
	int ans=inf;
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
	 	ans=min(ans,quemn(1,dfn[top[x]],dfn[x]));
	 	x=fa[top[x]];
	 }
	 if(dep[x]<dep[y]) swap(x,y);
	 if(y!=x) ans=min(ans,quemn(1,dfn[y]+1,dfn[x]));
	 return ans;
}
int que_cmx(int x,int y){		//chain query
	int ans=-inf;
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
	 	ans=max(ans,quemx(1,dfn[top[x]],dfn[x]));
	 	x=fa[top[x]];
	 }
	 if(dep[x]<dep[y]) swap(x,y);
	 if(y!=x) ans=max(ans,quemx(1,dfn[y]+1,dfn[x]));
	 return ans;
}
PII ee[N];
int main(){
	int n,q;scanf("%d",&n);
	for(int i=1,u,v,w;i<n;i++){
		scanf("%d%d%d",&u,&v,&w),u++,v++;
		ee[i]={u,v};
		add(u,v,w);
	}
	dfs(1,0),dfs1(1,0);bud(1,1,n);
	//Print(dep,n);return 0;
	scanf("%d",&q);while(q--){
		char op[5];int u,v;
		scanf("\\n%s%d%d",op,&u,&v);
		if(op[0]!='C') u++,v++;
		if(op[0]=='C'){
			int x=dep[ee[u].fiLUOGU P1505 [国家集训队]旅游 (树链剖分+线段树)

P1505 [国家集训队]旅游

p1505[国家集训队]旅游

P1505 [国家集训队]旅游树链剖分

[国家集训队]旅游

BZOJ_2157_旅游_树剖+线段树