标签:cst using main node [1] 取反 val iostream 输入
题意:给一颗树,边上有权有三种操作
Q u,v u->v路径上权的最大值
C u,v 输入时的第u条边权值修改为v
N u,v u->v路径上边的权值*-1
按照轻重边剖分,取反加个标记就好,记录最大值最小值,取反的时候反过来,再*-1,完成取反操作
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define lc rt<<1
#define rc rt<<1|1
using namespace std;
const int maxn=1e4+5;
const int INF=1e9;
struct Node{int l,r,mx,mi;bool mark;}tr[maxn*4];
struct edge{int to,nxt,v;}e[maxn*3];
int fa[maxn],dep[maxn],son[maxn],siz[maxn],top[maxn];
int p[maxn],cnt,node,val[maxn],fp[maxn],head[maxn];
void addedge(int u,int v,int w){
cnt++;e[cnt].to=v;e[cnt].nxt=head[u];
e[cnt].v=w;head[u]=cnt;
}
void dfs1(int u){
siz[u]=1;son[u]=0;
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
if(v==fa[u])continue;
fa[v]=u;dep[v]=dep[u]+1;val[v]=e[i].v;
dfs1(v);
siz[u]+=siz[v];
if(siz[v]>siz[son[u]])son[u]=v;
}
}
void dfs2(int u,int sp){
p[u]=++node;top[u]=sp;fp[node]=u;
if(son[u])dfs2(son[u],top[u]);
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
if(v!=fa[u]&&v!=son[u])dfs2(v,v);
}
}
inline void pushup(int rt){
tr[rt].mx=max(tr[lc].mx,tr[rc].mx);
tr[rt].mi=min(tr[lc].mi,tr[rc].mi);
}
inline void pushdown(int rt){
if(tr[rt].mark){
swap(tr[lc].mi,tr[lc].mx);tr[lc].mi*=-1;
swap(tr[rc].mi,tr[rc].mx);tr[rc].mi*=-1;
tr[lc].mx*=-1;tr[rc].mx*=-1;
tr[lc].mark^=1;tr[rc].mark^=1;
tr[rt].mark^=1;
}
}
void build(int rt,int l,int r){
tr[rt].l=l;tr[rt].r=r;tr[rt].mark=false;
if(l==r){
tr[rt].mi=tr[rt].mx=val[fp[l]];
}
else{
int m=(l+r)>>1;
build(lc,l,m);build(rc,m+1,r);
pushup(rt);
}
}
void update(int rt,int pp,int v){
int l=tr[rt].l,r=tr[rt].r;
if(l==r)tr[rt].mx=tr[rt].mi=v;
else{
pushdown(rt);
int m=(l+r)>>1;
if(pp<=m)update(lc,pp,v);
else update(rc,pp,v);
pushup(rt);
}
}
void anti(int rt,int a,int b){
int l=tr[rt].l,r=tr[rt].r;
if(l==a&&b==r){
tr[rt].mark^=1;swap(tr[rt].mx,tr[rt].mi);
tr[rt].mx*=-1;tr[rt].mi*=-1;
}
else{
pushdown(rt);
int m=(l+r)>>1;
if(b<=m) anti(lc,a,b);
else if(m<a)anti(rc,a,b);
else anti(lc,a,m),anti(rc,m+1,b);
pushup(rt);
}
}
int query(int rt,int a,int b){
int l=tr[rt].l,r=tr[rt].r;
if(l==a&&b==r)return tr[rt].mx;
else{
pushdown(rt);
int m=(l+r)>>1;
if(b<=m)return query(lc,a,b);
else if(m<a)return query(rc,a,b);
else return max(query(lc,a,m),query(rc,m+1,b));
}
}
void change(int u,int v){
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]])swap(u,v);
anti(1,p[top[u]],p[u]);
u=fa[top[u]];
}
if(u==v)return ;
if(dep[u]>dep[v])swap(u,v);
anti(1,p[son[u]],p[v]);
}
int ask(int u,int v){
int ans=-INF;
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]])swap(u,v);
ans=max(ans,query(1,p[top[u]],p[u]));
u=fa[top[u]];
}
if(u==v)return ans;
if(dep[u]>dep[v])swap(u,v);
return max(ans,query(1,p[son[u]],p[v]));
}
int ee[maxn][2],u,v,w;
int main(){
int t,n;scanf("%d",&t);
while(t--){
scanf("%d",&n);
cnt=node=0;memset(head,0,sizeof(head));
for(int i=1;i<n;i++){
scanf("%d%d%d",&ee[i][0],&ee[i][1],&w);
addedge(ee[i][0],ee[i][1],w);
addedge(ee[i][1],ee[i][0],w);
}
dfs1(1);dfs2(1,1);
build(1,1,n);
char op[10];
for(int i=1;i<n;i++)if(dep[ee[i][0]]>dep[ee[i][1]])swap(ee[i][0],ee[i][1]);
while(true){
scanf("%s",op);
if(op[0]==‘D‘)break;
scanf("%d%d",&u,&v);
if(op[0]==‘C‘){
u=ee[u][1];
update(1,p[u],v);
}
else if(op[0]==‘Q‘)printf("%d\n",ask(u,v));
else change(u,v);
}
}
return 0;
}
标签:cst using main node [1] 取反 val iostream 输入
原文地址:http://www.cnblogs.com/jihe/p/5987263.html