樹鏈剖分模板題彙總
阿新 • • 發佈:2019-01-23
記錄幾個樹鏈剖分的模板題,包括點操作,邊操作和帶方向的操作。
點操作
HDU 3966
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <queue>
#include <tr1/unordered_set>
//#include <tr1/unordered_map>
#include <bitset>
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define inf 1e9
#define debug(a) cout << #a" = " << (a) << endl;
#define debugarry(a, n) for (int i = 0; i < (n); i++) { cout << #a"[" << i << "] = " << (a)[i] << endl; }
#define clr(x, y) memset(x, y, sizeof x)
#define ll long long
#define ull unsigned long long
#define FOR(i,a,b) \
for(i=a;a<b?i<=b:i>=b;a<b?i++:i--)
const int maxn = 50000+200;
struct sad
{
int to,next;
}G[maxn<<2];
int h[maxn],si;
void add(int u,int v)
{
G[si].to=v;
G[si].next=h[u];
h[u]=si++;
}
int siz[maxn],dep[maxn];
int fa[maxn],son[maxn],top[maxn];
void dfs1(int u,int f,int d)
{
fa[u] = f;
dep[u] = d;
siz[u] = 1;
son[u] = -1;
for(int i=h[u];~i;i=G[i].next){
int v=G[i].to;
if( v != f )
{
dfs1(v,u,d+1);
siz[u] += siz[v];
if(son[u]==-1||siz[son[u]]<siz[v])
son[u]=v;
}
}
}
int p[maxn],fp[maxn],pos;
void dfs2(int u,int sf)
{
top[u]=sf;
p[u]=pos++;
fp[p[u]]=u;
if( son[u] == -1 ) return ;
dfs2(son[u],sf);
for(int i=h[u];~i;i=G[i].next)
{
int v=G[i].to;
if(son[u]!=v&&fa[u]!=v)
dfs2(v,v);
}
}
int rs[maxn];
void upp(int x,int p)
{
while(x<=pos)
{
rs[x]+=p;
x+=x&-x;
}
}
int get(int x)
{
int ret=0;
while(x)
{
ret += rs[x];
x-=x&-x;
}
return ret;
}
void Change(int u,int v,int d)
{
int f1=top[u] , f2=top[v];
while(f1 != f2){
if( dep[f1] < dep[f2] )
{
swap(f1,f2);
swap(u,v);
}
upp(p[f1],d);
upp(p[u]+1,-d);
u=fa[f1];
f1=top[u];
}
if( dep[u] > dep[v] ) swap(u,v);
upp(p[u],d);
upp(p[v]+1,-d);
}
int A[maxn];
int main()
{
//freopen("input.txt","r",stdin);
int n,m,P,u,v,d;
char c;
while(~scanf("%d%d%d",&n,&m,&P))
{
clr(h,-1);
si=0;
clr(rs,0);
pos=1;
for(int i=1;i<=n;i++)
scanf("%d",&A[i]);
for(int i=0;i<n-1;i++)
{
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
dfs1(1,-1,1);
dfs2(1,1);
for(int i=1;i<=n;i++)
Change(i,i,A[i]);
for(int i=0;i<P;i++)
{
scanf(" %c",&c);
if( c == 'Q' )
{
scanf("%d",&u);
printf("%d\n",get(p[u]));
}else{
scanf("%d%d%d",&u,&v,&d);
if( c == 'D' ) d*=-1;
Change(u,v,d);
}
}
}
return 0;
}
HYSBZ 1036
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <queue>
//#include <tr1/unordered_set>
//#include <tr1/unordered_map>
#include <bitset>
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define inf 1e9
#define debug(a) cout << #a" = " << (a) << endl;
#define debugarry(a, n) for (int i = 0; i < (n); i++) { cout << #a"[" << i << "] = " << (a)[i] << endl; }
#define clr(x, y) memset(x, y, sizeof x)
#define ll long long
#define ull unsigned long long
#define FOR(i,a,b) \
for(i=a;a<b?i<=b:i>=b;a<b?i++:i--)
const int maxn = 30000 + 30;
struct edge{
int to,next;
}G[maxn<<2];
int h[maxn],si;
void add(int u,int v){
G[si].to=v;
G[si].next=h[u];
h[u]=si++;
}
int siz[maxn],dep[maxn];
int fa[maxn],son[maxn],top[maxn];
void dfs1(int u,int f,int d){
fa[u]=f;
dep[u]=d;
siz[u]=1;
son[u]=-1;
for(int i=h[u];~i;i=G[i].next){
int v=G[i].to;
if(v^f){
dfs1(v,u,d+1);
siz[u]+=siz[v];
if(son[u]==-1||siz[son[u]]<siz[v])
son[u]=v;
}
}
}
int p[maxn],fp[maxn],pos;
void dfs2(int u,int sf){
top[u]=sf;
p[u]=pos++;
fp[p[u]]=u;
if(son[u]==-1) return ;
dfs2(son[u],sf);
for(int i=h[u];~i;i=G[i].next){
int v=G[i].to;
if(son[u]!=v&&fa[u]!=v)
dfs2(v,v);
}
}
int w[maxn];
int rs[maxn<<2],rm[maxn<<2];
void pushup(int rt){
rs[rt] = rs[rt<<1] + rs[rt<<1|1];
rm[rt] = max(rm[rt<<1],rm[rt<<1|1]);
}
void build(int l,int r,int rt){
if(l==r){
rs[rt] = rm[rt] = w[fp[l]];
return ;
}
int m=l+r>>1;
build(lson);
build(rson);
pushup(rt);
}
void update(int pos,int v,int l,int r,int rt){
if(l==r){
rs[rt] = rm[rt] = v;
return ;
}
int m=l+r>>1;
if( pos <= m ) update(pos,v,lson);
else update(pos,v,rson);
pushup(rt);
}
int qs,qm;
void query(int L,int R,int l,int r,int rt){
if(L<=l&&r<=R){
qs += rs[rt];
qm = max(qm,rm[rt]);
return ;
}
int m=l+r>>1;
if( L <= m ) query(L,R,lson);
if( m < R ) query(L,R,rson);
}
void Query(int u,int v){
int f1=top[u],f2=top[v];
while(f1!=f2){
if(dep[f1]<dep[f2]){
swap(f1,f2);
swap(u,v);
}
query(p[f1],p[u],1,pos-1,1);
u=fa[f1];
f1=top[u];
}
if( dep[u] > dep[v] ) swap(u,v);
query(p[u],p[v],1,pos-1,1);
}
void init()
{
clr(h,-1);
si=0;
pos=1;
}
char s[200];
int main()
{
//freopen("input.txt","r",stdin);
int n;
while(~scanf("%d",&n)){
init();
int u,v;
for(int i=0;i<n-1;i++){
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
for(int i=1;i<=n;i++)
scanf("%d",&w[i]);
dfs1(1,-1,1);
dfs2(1,1);
build(1,pos-1,1);
int q;
scanf("%d",&q);
for(int i=0;i<q;i++){
scanf("%s%d%d",s,&u,&v);
if(!strcmp(s,"CHANGE"))
update(p[u],v,1,pos-1,1);
else if(!strcmp(s,"QMAX"))
{
qm = -inf;
Query(u,v);
printf("%d\n",qm);
}else{
qs=0;
Query(u,v);
printf("%d\n",qs);
}
}
}
return 0;
}
LightOJ 1348
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <queue>
//#include <tr1/unordered_set>
//#include <tr1/unordered_map>
#include <bitset>
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define inf 1e9
#define debug(a) cout << #a" = " << (a) << endl;
#define debugarry(a, n) for (int i = 0; i < (n); i++) { cout << #a"[" << i << "] = " << (a)[i] << endl; }
#define clr(x, y) memset(x, y, sizeof x)
#define ll long long
#define ull unsigned long long
#define FOR(i,a,b) \
for(i=a;a<b?i<=b:i>=b;a<b?i++:i--)
const int maxn = 30000+300;
struct edge{
int to,next;
}G[maxn<<2];
int h[maxn],si;
void add(int u,int v){
G[si].to=v;
G[si].next=h[u];
h[u]=si++;
}
int siz[maxn],dep[maxn];
int fa[maxn],son[maxn],top[maxn];
void dfs1(int u,int f,int d){
fa[u]=f;
dep[u]=d;
siz[u]=1;
son[u]=-1;
for(int i=h[u];~i;i=G[i].next){
int v=G[i].to;
if(v^f){
dfs1(v,u,d+1);
siz[u]+=siz[v];
if(son[u]==-1||siz[son[u]]<siz[v])
son[u]=v;
}
}
}
int p[maxn],fp[maxn],pos;
void dfs2(int u,int sf){
top[u]=sf;
p[u]=pos++;
fp[p[u]]=u;
if(son[u]==-1) return ;
dfs2(son[u],sf);
for(int i=h[u];~i;i=G[i].next){
int v=G[i].to;
if(son[u]!=v&&fa[u]!=v)
dfs2(v,v);
}
}
int rs[maxn];
void upp(int x,int p){
while(x<=pos){
rs[x]+=p;
x+=x&-x;
}
}
int get(int x){
int ret=0;
while(x){
ret += rs[x];
x-=x&-x;
}
return ret;
}
int Query(int u,int v){
int tmp=0;
int f1=top[u],f2=top[v];
while(f1^f2){
if(dep[f1]<dep[f2]){
swap(f1,f2);
swap(u,v);
}
tmp += get(p[u]) - get(p[f1]-1);
u=fa[f1];
f1=top[u];
}
if( dep[u] > dep[v] ) swap(u,v);
tmp += get(p[v]) - get(p[u]-1);
return tmp;
}
void init()
{
clr(h,-1);
si=0;
pos=1;
}
int w[maxn];
int main()
{
// freopen("input.txt","r",stdin);
int T,CASE=0;
scanf("%d",&T);
while(T--){
init();
clr(rs,0);
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&w[i]);
int a,b;
for(int i=0;i<n-1;i++)
{
scanf("%d%d",&a,&b);
add(a,b);
add(b,a);
}
dfs1(0,-1,1);
dfs2(0,0);
for(int i=0;i<n;i++)
upp(p[i],w[i]);
int q,c;
scanf("%d",&q);
printf("Case %d:\n",++CASE);
for(int i=0;i<q;i++){
scanf("%d%d%d",&c,&a,&b);
if( c == 0 )
printf("%d\n",Query(a,b));
else
{
upp(p[a],b-w[a]);
w[a]=b;
}
}
}
return 0;
}
邊操作
SPOJ QTREE
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <queue>
//#include <tr1/unordered_set>
//#include <tr1/unordered_map>
#include <bitset>
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define inf 1e9
#define debug(a) cout << #a" = " << (a) << endl;
#define debugarry(a, n) for (int i = 0; i < (n); i++) { cout << #a"[" << i << "] = " << (a)[i] << endl; }
#define clr(x, y) memset(x, y, sizeof x)
#define ll long long
#define ull unsigned long long
#define FOR(i,a,b) \
for(i=a;a<b?i<=b:i>=b;a<b?i++:i--)
const int maxn = 10000+20;
struct sad
{
int to,next,id;
}G[maxn<<2];
int h[maxn],si;
void add(int u,int v,int id){
G[si].to=v;
G[si].id=id;
G[si].next=h[u];
h[u]=si++;
}
int siz[maxn],dep[maxn];
int fa[maxn],son[maxn],top[maxn];
int fid[maxn];
void dfs1(int u,int f,int d)
{
fa[u]=f;
dep[u]=d;
siz[u]=1;
son[u]=-1;
for(int i=h[u];~i;i=G[i].next){
int v=G[i].to;
if(v^f){
fid[G[i].id]=v;
dfs1(v,u,d+1);
siz[u]+=siz[v];
if(son[u]==-1||siz[son[u]]<siz[v])
son[u]=v;
}
}
}
int p[maxn],fp[maxn],pos;
void dfs2(int u,int sf)
{
top[u]=sf;
p[u]=pos++;
fp[p[u]]=u;
if(son[u]==-1) return ;
dfs2(son[u],sf);
for(int i=h[u];~i;i=G[i].next){
int v=G[i].to;
if(son[u]!=v&&fa[u]!=v)
dfs2(v,v);
}
}
int col[maxn<<2],ma[maxn<<2],mi[maxn<<2];
void pushdown(int rt)
{
if(col[rt])
{
col[rt<<1] ^= 1;
col[rt<<1|1] ^= 1;
swap(ma[rt<<1],mi[rt<<1]);
ma[rt<<1]*=-1;
mi[rt<<1]*=-1;
swap(ma[rt<<1|1],mi[rt<<1|1]);
ma[rt<<1|1]*=-1;
mi[rt<<1|1]*=-1;
col[rt]=0;
}
}
void pushup(int rt)
{
ma[rt] = max(ma[rt<<1],ma[rt<<1|1]);
mi[rt] = min(mi[rt<<1],mi[rt<<1|1]);
}
void build(int l,int r,int rt)
{
col[rt]=0;
if(l==r)
{
ma[rt]=mi[rt]=0;
return ;
}
int m=l+r>>1;
build(lson);
build(rson);
pushup(rt);
}
void update(int pos,int v,int l,int r,int rt)
{
if(l==r)
{
ma[rt]=mi[rt]=v;
return ;
}
pushdown(rt);
int m=l+r>>1;
if( pos <= m ) update(pos,v,lson);
else update(pos,v,rson);
pushup(rt);
}
void update2(int L,int R,int l,int r,int rt)
{
if( L <= l && r <= R )
{
swap(ma[rt],mi[rt]);
ma[rt]*=-1;
mi[rt]*=-1;
col[rt] ^= 1;
return ;
}
pushdown(rt);
int m=l+r>>1;
if( L <= m ) update2(L,R,lson);
if( m < R ) update2(L,R,rson);
pushup(rt);
}
int query(int L,int R,int l,int r,int rt)
{
if( L <= l && r <= R )
return ma[rt];
int ret=-inf;
int m=l+r>>1;
pushdown(rt);
if( L <= m ) ret = max(ret,query(L,R,lson));
if( m < R ) ret = max(ret,query(L,R,rson));
return ret;
}
void Change(int u,int v)
{
int f1=top[u],f2=top[v];
while(f1!=f2){
if(dep[f1]<dep[f2]){
swap(f1,f2);
swap(u,v);
}
update2(p[f1],p[u],1,pos-1,1);
u=fa[f1];
f1=top[u];
}
if(u==v) return ;
if(dep[u]>dep[v]) swap(u,v);
update2(p[son[u]],p[v],1,pos-1,1);
}
int Query(int u,int v){
int ret=-inf;
int f1=top[u],f2=top[v];
while(f1!=f2){
if(dep[f1]<dep[f2]){
swap(f1,f2);
swap(u,v);
}
ret = max(ret,query(p[f1],p[u],1,pos-1,1));
u=fa[f1];
f1=top[u];
}
if(u==v) return ret;
if(dep[u]>dep[v]) swap(u,v);
ret = max(ret,query(p[son[u]],p[v],1,pos-1,1));
return ret;
}
void init(){
clr(h,-1);
si=0;
pos=1;
}
int w[maxn];
char s[100];
int main()
{
// freopen("input.txt","r",stdin);
int T,n;
scanf("%d",&T);
while(T--){
init();
scanf("%d",&n);
int a,b;
for(int i=1;i<=n-1;i++){
scanf("%d%d%d",&a,&b,&w[i]);
add(a,b,i);
add(b,a,i);
}
dfs1(1,-1,1);
dfs2(1,1);
build(1,pos-1,1);
for(int i=1;i<=n-1;i++)
update(p[fid[i]],w[i],1,pos-1,1);
while(~scanf("%s",s))
{
if(!strcmp(s,"QUERY"))
{
scanf("%d%d",&a,&b);
printf("%d\n",Query(a,b));
}else if(!strcmp(s,"NEGATE"))
{
scanf("%d%d",&a,&b);
Change(a,b);
}else if(!strcmp(s,"CHANGE"))
{
scanf("%d%d",&a,&b);
update(p[fid[a]],b,1,pos-1,1);
}else
break;
}
}
return 0;
}
POJ 2763
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <queue>
//#include <tr1/unordered_set>
//#include <tr1/unordered_map>
#include <bitset>
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define inf 1e9
#define debug(a) cout << #a" = " << (a) << endl;
#define debugarry(a, n) for (int i = 0; i < (n); i++) { cout << #a"[" << i << "] = " << (a)[i] << endl; }
#define clr(x, y) memset(x, y, sizeof x)
#define ll long long
#define ull unsigned long long
#define FOR(i,a,b) \
for(i=a;a<b?i<=b:i>=b;a<b?i++:i--)
const int maxn = 100001+20;
struct sad{
int to,next,id;
}G[maxn<<2];
int h[maxn],si;
void add(int u,int v,int id)
{
G[si].to=v;
G[si].id=id;
G[si].next=h[u];
h[u]=si++;
}
int siz[maxn],dep[maxn];
int fa[maxn],son[maxn],top[maxn];
int fid[maxn];
void dfs1(int u,int f,int d)
{
// debug(u);
fa[u]=f;
dep[u]=d;
siz[u]=1;
son[u]=-1;
for(int i=h[u];~i;i=G[i].next){
int v=G[i].to;
// debug(v);
if(v!=f){
fid[G[i].id]=v;
dfs1(v,u,d+1);
siz[u] += siz[v];
if(son[u]==-1||siz[son[u]]<siz[v])
son[u]=v;
}
}
}
int p[maxn],fp[maxn],pos;
void dfs2(int u,int sf)
{
top[u]=sf;
p[u]=pos++;
fp[p[u]]=u;
if(son[u]==-1) return ;
dfs2(son[u],sf);
for(int i=h[u];~i;i=G[i].next)
{
int v=G[i].to;
if(son[u]!=v&&fa[u]!=v)
dfs2(v,v);
}
}
int rs[maxn];
void upp(int x,int p)
{
while(x<=pos)
{
rs[x]+=p;
x+=x&-x;
}
}
int get(int x)
{
int ret=0;
while(x)
{
ret += rs[x];
x-=x&-x;
}
return ret;
}
int Query(int u,int v)
{
int ret=0,f1=top[u],f2=top[v];
while(f1!=f2)
{
if(dep[f1]<dep[f2])
{
swap(f1,f2);
swap(u,v);
}
ret += get(p[u]) - get(p[f1]-1);
u=fa[f1];
f1=top[u];
}
if(u==v) return ret;
if(dep[u]>dep[v]) swap(u,v);
ret += get(p[v]) - get(p[son[u]]-1);
return ret;
}
void init()
{
clr(h,-1);
si=0;
pos=1;
}
int w[maxn];
int main()
{
// freopen("input.txt","r",stdin);
int n,q,s,u,v;
while(~scanf("%d%d%d",&n,&q,&s))
{
init();
clr(rs,0);
for(int i=1;i<=n-1;i++)
{
scanf("%d%d%d",&u,&v,&w[i]);
add(u,v,i);
add(v,u,i);
}
dfs1(1,-1,1);
dfs2(1,1);
for(int i=1;i<=n-1;i++)
upp(p[fid[i]],w[i]);
int c;
for(int i=0;i<q;i++)
{
scanf("%d",&c);
if(c==0)
{
scanf("%d",&u);
printf("%d\n",Query(s,u));
s=u;
}else{
int a,b;
scanf("%d%d",&a,&b);
upp(p[fid[a]],b-w[a]);
w[a]=b;
}
}
}
return 0;
}
POJ 3237
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <queue>
//#include <tr1/unordered_set>
//#include <tr1/unordered_map>
#include <bitset>
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define inf 1e9
#define debug(a) cout << #a" = " << (a) << endl;
#define debugarry(a, n) for (int i = 0; i < (n); i++) { cout << #a"[" << i << "] = " << (a)[i] << endl; }
#define clr(x, y) memset(x, y, sizeof x)
#define ll long long
#define ull unsigned long long
#define FOR(i,a,b) \
for(i=a;a<b?i<=b:i>=b;a<b?i++:i--)
const int maxn = 10000+20;
struct sad
{
int to,next,id;
}G[maxn<<2];
int h[maxn],si;
void add(int u,int v,int id){
G[si].to=v;
G[si].id=id;
G[si].next=h[u];
h[u]=si++;
}
int siz[maxn],dep[maxn];
int fa[maxn],son[maxn],top[maxn];
int fid[maxn];
void dfs1(int u,int f,int d)
{
fa[u]=f;
dep[u]=d;
siz[u]=1;
son[u]=-1;
for(int i=h[u];~i;i=G[i].next){
int v=G[i].to;
if(v^f){
fid[G[i].id]=v;
dfs1(v,u,d+1);
siz[u]+=siz[v];
if(son[u]==-1||siz[son[u]]<siz[v])
son[u]=v;
}
}
}
int p[maxn],fp[maxn],pos;
void dfs2(int u,int sf)
{
top[u]=sf;
p[u]=pos++;
fp[p[u]]=u;
if(son[u]==-1) return ;
dfs2(son[u],sf);
for(int i=h[u];~i;i=G[i].next){
int v=G[i].to;
if(son[u]!=v&&fa[u]!=v)
dfs2(v,v);
}
}
int col[maxn<<2],ma[maxn<<2],mi[maxn<<2];
void pushdown(int rt)
{
if(col[rt])
{
col[rt<<1] ^= 1;
col[rt<<1|1] ^= 1;
swap(ma[rt<<1],mi[rt<<1]);
ma[rt<<1]*=-1;
mi[rt<<1]*=-1;
swap(ma[rt<<1|1],mi[rt<<1|1]);
ma[rt<<1|1]*=-1;
mi[rt<<1|1]*=-1;
col[rt]=0;
}
}
void pushup(int rt)
{
ma[rt] = max(ma[rt<<1],ma[rt<<1|1]);
mi[rt] = min(mi[rt<<1],mi[rt<<1|1]);
}
void build(int l,int r,int rt)
{
col[rt]=0;
if(l==r)
{
ma[rt]=mi[rt]=0;
return ;
}
int m=l+r>>1;
build(lson);
build(rson);
pushup(rt);
}
void update(int pos,int v,int l,int r,int rt)
{
if(l==r)
{
ma[rt]=mi[rt]=v;
return ;
}
pushdown(rt);
int m=l+r>>1;
if( pos <= m ) update(pos,v,lson);
else update(pos,v,rson);
pushup(rt);
}
void update2(int L,int R,int l,int r,int rt)
{
if( L <= l && r <= R )
{
swap(ma[rt],mi[rt]);
ma[rt]*=-1;
mi[rt]*=-1;
col[rt] ^= 1;
return ;
}
pushdown(rt);
int m=l+r>>1;
if( L <= m ) update2(L,R,lson);
if( m < R ) update2(L,R,rson);
pushup(rt);
}
int query(int L,int R,int l,int r,int rt)
{
if( L <= l && r <= R )
return ma[rt];
int ret=-inf;
int m=l+r>>1;
pushdown(rt);
if( L <= m ) ret = max(ret,query(L,R,lson));
if( m < R ) ret = max(ret,query(L,R,rson));
return ret;
}
void Change(int u,int v)
{
int f1=top[u],f2=top[v];
while(f1!=f2){
if(dep[f1]<dep[f2]){
swap(f1,f2);
swap(u,v);
}
update2(p[f1],p[u],1,pos-1,1);
u=fa[f1];
f1=top[u];
}
if(u==v) return ;
if(dep[u]>dep[v]) swap(u,v);
update2(p[son[u]],p[v],1,pos-1,1);
}
int Query(int u,int v){
int ret=-inf;
int f1=top[u],f2=top[v];
while(f1!=f2){
if(dep[f1]<dep[f2]){
swap(f1,f2);
swap(u,v);
}
ret = max(ret,query(p[f1],p[u],1,pos-1,1));
u=fa[f1];
f1=top[u];
}
if(u==v) return ret;
if(dep[u]>dep[v]) swap(u,v);
ret = max(ret,query(p[son[u]],p[v],1,pos-1,1));
return ret;
}
void init(){
clr(h,-1);
si=0;
pos=1;
}
int w[maxn];
char s[100];
int main()
{
// freopen("input.txt","r",stdin);
int T,n;
scanf("%d",&T);
while(T--){
init();
scanf("%d",&n);
int a,b;
for(int i=1;i<=n-1;i++){
scanf("%d%d%d",&a,&b,&w[i]);
add(a,b,i);
add(b,a,i);
}
dfs1(1,-1,1);
dfs2(1,1);
build(1,pos-1,1);
for(int i=1;i<=n-1;i++)
update(p[fid[i]],w[i],1,pos-1,1);
while(~scanf("%s",s))
{
if(!strcmp(s,"QUERY"))
{
scanf("%d%d",&a,&b);
printf("%d\n",Query(a,b));
}else if(!strcmp(s,"NEGATE"))
{
scanf("%d%d",&a,&b);
Change(a,b);
}else if(!strcmp(s,"CHANGE"))
{
scanf("%d%d",&a,&b);
update(p[fid[a]],b,1,pos-1,1);
}else
break;
}
}
return 0;
}
FZU 2082
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>