题目链接:https://www.luogu.org/problemnew/show/P1505
题目大意:
Ray 乐忠于旅游,这次他来到了T 城。T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接。为了方便游客到达每个景点但又为了节约成本,T 城的任意两个景点之间有且只有一条路径。换句话说, T 城中只有N − 1 座桥。
Ray 发现,有些桥上可以看到美丽的景色,让人心情愉悦,但有些桥狭窄泥泞,令人烦躁。于是,他给每座桥定义一个愉悦度w,也就是说,Ray 经过这座桥会增加w 的愉悦度,这或许是正的也可能是负的。有时,Ray 看待同一座桥的心情也会发生改变。
现在,Ray 想让你帮他计算从u 景点到v 景点能获得的总愉悦度。有时,他还想知道某段路上最美丽的桥所提供的最大愉悦度,或是某段路上最糟糕的一座桥提供的最低愉悦度。
题目思路:边权转点权,权给儿子。 lazy标记,取相反数,maxx取相反给minn,minn取相反给maxx,sum取相反数
以下是代码:
#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
#define ll long long
#define inf 0x7fffffff
const int MAXN = 2e5+5;
struct nod{
int to,w;
}p;
char s[MAXN];
int fa[MAXN],siz[MAXN],son[MAXN],rk[MAXN],dep[MAXN],dfn[MAXN],top[MAXN],w[MAXN],tot;
vector<nod>v[MAXN];
void dfs1(int u,int f){
dep[u]=dep[f]+1;
siz[u]=1;
fa[u]=f;
son[u]=0;
int len=v[u].size();
rep(i,0,len-1){
int to=v[u][i].to;
if(to==f)continue;
w[to]=v[u][i].w;
dfs1(to,u);
siz[u]+=siz[to];
if(siz[to]>siz[son[u]]){
son[u]=to;
}
}
}
void dfs2(int u,int tp){
dfn[u]=++tot;rk[tot]=u;
top[u]=tp;
int len=v[u].size();
if(son[u])dfs2(son[u],tp);
rep(i,0,len-1){
int to=v[u][i].to;
if(to==fa[u]||to==son[u])continue;
dfs2(to,to);
}
}
struct edge{
int x,y;
}b[MAXN];
struct node{
int l,r,sum,maxx,minn,lazy;
}a[MAXN<<2];
void build(int rt,int l,int r){
a[rt].l=l,a[rt].r=r,a[rt].lazy=0;
if(l==r){
a[rt].sum=a[rt].maxx=a[rt].minn=w[rk[l]];
return;
}
int mid=(l+r)>>1;
build(rt<<1,l,mid);
build(rt<<1|1,mid+1,r);
a[rt].sum=a[rt<<1].sum+a[rt<<1|1].sum;
a[rt].maxx=max(a[rt<<1].maxx,a[rt<<1|1].maxx);
a[rt].minn=min(a[rt<<1].minn,a[rt<<1|1].minn);
}
void spread(int rt){
if(a[rt].lazy){
a[rt<<1].sum=-a[rt<<1].sum;
a[rt<<1|1].sum=-a[rt<<1|1].sum;
int temp=a[rt<<1].minn;
a[rt<<1].minn=-a[rt<<1].maxx;
a[rt<<1].maxx=-temp;
temp=a[rt<<1|1].minn;
a[rt<<1|1].minn=-a[rt<<1|1].maxx;
a[rt<<1|1].maxx=-temp;
a[rt<<1].lazy^=1;
a[rt<<1|1].lazy^=1;
a[rt].lazy=0;
}
}
void update(int rt,int x,int y){
if(a[rt].l==x&&a[rt].r==x){
a[rt].sum=a[rt].maxx=a[rt].minn=y;
return;
}
spread(rt);
int mid=(a[rt].l+a[rt].r)>>1;
if(x<=mid)update(rt<<1,x,y);
else update(rt<<1|1,x,y);
a[rt].sum=a[rt<<1].sum+a[rt<<1|1].sum;
a[rt].maxx=max(a[rt<<1].maxx,a[rt<<1|1].maxx);
a[rt].minn=min(a[rt<<1].minn,a[rt<<1|1].minn);
}
void update2(int rt,int l,int r){
if(a[rt].l>=l&&a[rt].r<=r){
a[rt].sum*=-1;
int temp=a[rt].minn;
a[rt].minn=-a[rt].maxx;
a[rt].maxx=-temp;
a[rt].lazy^=1;
return;
}
spread(rt);
int mid=(a[rt].l+a[rt].r)>>1;
if(l<=mid)update2(rt<<1,l,r);
if(r>mid)update2(rt<<1|1,l,r);
a[rt].sum=a[rt<<1].sum+a[rt<<1|1].sum;
a[rt].maxx=max(a[rt<<1].maxx,a[rt<<1|1].maxx);
a[rt].minn=min(a[rt<<1].minn,a[rt<<1|1].minn);
}
void update1(int x,int y){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
update2(1,dfn[top[x]],dfn[x]);
x=fa[top[x]];
}
if(dfn[x]>dfn[y])swap(x,y);
update2(1,dfn[x]+1,dfn[y]);
}
int query(int rt,int l,int r){
if(a[rt].l>=l&&a[rt].r<=r){
return a[rt].sum;
}
spread(rt);
int mid=(a[rt].l+a[rt].r)>>1,ans=0;
if(l<=mid)ans+=query(rt<<1,l,r);
if(r>mid)ans+=query(rt<<1|1,l,r);
return ans;
}
int query1(int x,int y){
int ans=0;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
ans+=query(1,dfn[top[x]],dfn[x]);
x=fa[top[x]];
}
if(dfn[x]>dfn[y])swap(x,y);
ans+=query(1,dfn[x]+1,dfn[y]);
return ans;
}
int query2(int rt,int l,int r){
if(a[rt].l>=l&&a[rt].r<=r){
return a[rt].maxx;
}
spread(rt);
int mid=(a[rt].l+a[rt].r)>>1,ans=-inf;
if(l<=mid)ans=max(ans,query2(rt<<1,l,r));
if(r>mid)ans=max(ans,query2(rt<<1|1,l,r));
return ans;
}
int query3(int x,int y){
int ans=-inf;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
ans=max(ans,query2(1,dfn[top[x]],dfn[x]));
x=fa[top[x]];
}
if(dfn[x]>dfn[y])swap(x,y);
ans=max(ans,query2(1,dfn[x]+1,dfn[y]));
return ans;
}
int query4(int rt,int l,int r){
if(a[rt].l>=l&&a[rt].r<=r){
return a[rt].minn;
}
spread(rt);
int mid=(a[rt].l+a[rt].r)>>1,ans=inf;
if(l<=mid)ans=min(ans,query4(rt<<1,l,r));
if(r>mid)ans=min(ans,query4(rt<<1|1,l,r));
return ans;
}
int query5(int x,int y){
int ans=inf;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
ans=min(ans,query4(1,dfn[top[x]],dfn[x]));
x=fa[top[x]];
}
if(dfn[x]>dfn[y])swap(x,y);
ans=min(ans,query4(1,dfn[x]+1,dfn[y]));
return ans;
}
int main(){
int n,m,x,y,z;
//while(~){
scanf("%d",&n);
rep(i,1,n)v[i].clear();
rep(i,1,n-1){
scanf("%d%d%d",&x,&y,&z);
x++;y++;
b[i].x=x,b[i].y=y;
p.to=y,p.w=z;
v[x].push_back(p);
p.to=x,p.w=z;
v[y].push_back(p);
}
dep[0]=0,tot=0;
w[0]=w[1]=0;
dfs1(1,0);
dfs2(1,1);
build(1,1,n);
scanf("%d",&m);
while(m--){
scanf("%s%d%d",s,&x,&y);
if(s[0]=='C'){
int u=b[x].x,v=b[x].y;
if(dep[u]<dep[v])swap(u,v);
update(1,dfn[u],y);
}
else if(s[0]=='N'){
x++;y++;
update1(x,y);
}
else if(s[0]=='S'){
x++;y++;
int ans=query1(x,y);
printf("%d\n",ans);
}
else if(s[1]=='A'){
x++;y++;
int ans=query3(x,y);
printf("%d\n",ans);
}
else if(s[1]=='I'){
x++;y++;
int ans=query5(x,y);
printf("%d\n",ans);
}
}
// }
return 0;
}