今天考试碰到一个树链剖分的模板题,由于脑抽一时忘记了整个子树是怎么修改的。。。。其实就是加上个siz。。。。
然后就找了一个操作比较全的树链剖分切了。。。。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define INF 0x3f3f3f3f
#define maxn 125000
int id,w[maxn],siz[maxn],val[maxn],en,ha[maxn],dep[maxn];
int first[maxn],next[maxn],to[maxn],top[maxn],fa[maxn],X[maxn],Y[maxn],Z[maxn];
int save[maxn],sum[maxn],minn[maxn],maxx[maxn],n,m,son[maxn];
bool rev[maxn];
void add(int a,int b,int c)
{
en++;
to[en]=b;
val[en]=c;
next[en]=first[a];
first[a]=en;
}
void dfs(int now)
{
int v,maxv=0;siz[now]=1;
for(int i=first[now];i;i=next[i])
{
v=to[i];
if(fa[now]==v) continue;
fa[v]=now;dep[v]=dep[now]+1;
dfs(v);
siz[now]+=siz[v];
if(maxv<siz[v])
{
maxv=siz[v];
son[now]=v;
}
}
}
void getid(int now,int root)
{
int v;id++;w[now]=id;top[now]=root;
if(son[now]) getid(son[now],root);
for(int i=first[now];i;i=next[i])
{
v=to[i];
if(v==son[now]||v==fa[now]) continue;
getid(v,v);
}
}
void pushup(int rt)
{
minn[rt]=min(minn[rt<<1],minn[rt<<1|1]);
maxx[rt]=max(maxx[rt<<1],maxx[rt<<1|1]);
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void pushdown(int rt)
{
if(rev[rt])
{
rev[rt]^=1;rev[rt<<1]^=1;rev[rt<<1|1]^=1;
sum[rt<<1]*=-1;sum[rt<<1|1]*=-1;
maxx[rt<<1]*=-1;minn[rt<<1]*=-1;
swap(maxx[rt<<1],minn[rt<<1]);
maxx[rt<<1|1]*=-1;minn[rt<<1|1]*=-1;
swap(maxx[rt<<1|1],minn[rt<<1|1]);
}
}
void update(int l,int r,int rt,int pos,int v)
{
if(l==r)
{
sum[rt]=maxx[rt]=minn[rt]=v;
return;
}
pushdown(rt);
int mid=(l+r)>>1;
if(pos<=mid) update(lson,pos,v);
else update(rson,pos,v);
pushup(rt);
}
void modify(int l,int r,int rt,int x,int y)
{
if(x<=l&&r<=y)
{
sum[rt]*=-1;
maxx[rt]*=-1;minn[rt]*=-1;
swap(maxx[rt],minn[rt]);
rev[rt]^=1;
return;
}
pushdown(rt);
int mid=(l+r)>>1;
if(x<=mid) modify(lson,x,y);
if(y>mid) modify(rson,x,y);
pushup(rt);
}
int getmax(int l,int r,int rt,int x,int y)
{
if(x<=l&&r<=y)
{
return maxx[rt];
}
pushdown(rt);
int ans=-INF;
int mid=(l+r)>>1;
if(x<=mid) ans=max(ans,getmax(lson,x,y));
if(y>mid) ans=max(ans,getmax(rson,x,y));
return ans;
}
int getmin(int l,int r,int rt,int x,int y)
{
if(x<=l&&r<=y)
{
return minn[rt];
}
pushdown(rt);
int ans=INF;
int mid=(l+r)>>1;
if(x<=mid) ans=min(ans,getmin(lson,x,y));
if(y>mid) ans=min(ans,getmin(rson,x,y));
return ans;
}
int getsum(int l,int r,int rt,int x,int y)
{
if(x<=l&&r<=y)
{
return sum[rt];
}
pushdown(rt);
int ans=0;
int mid=(l+r)>>1;
if(x<=mid) ans+=getsum(lson,x,y);
if(y>mid) ans+=getsum(rson,x,y);
return ans;
}
int getans1(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,getmax(1,n,1,w[top[x]],w[x]));
x=fa[top[x]];
}
if(x==y) return ans;
if(dep[x]>dep[y]) swap(x,y);
ans=max(ans,getmax(1,n,1,w[son[x]],w[y]));
return ans;
}
int getans2(int x,int y)
{
int ans=0;
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
ans+=getsum(1,n,1,w[top[x]],w[x]);
x=fa[top[x]];
}
if(x==y) return ans;
if(dep[x]>dep[y]) swap(x,y);
ans+=getsum(1,n,1,w[son[x]],w[y]);
return ans;
}
void getans3(int x,int y)
{
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
modify(1,n,1,w[top[x]],w[x]);
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
modify(1,n,1,w[son[x]],w[y]);
}
int getans4(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,getmin(1,n,1,w[top[x]],w[x]));
x=fa[top[x]];
}
if(x==y) return ans;
if(dep[x]>dep[y]) swap(x,y);
ans=min(ans,getmin(1,n,1,w[son[x]],w[y]));
return ans;
}
void build(int now)
{
int v;
for(int i=first[now];i;i=next[i])
{
v=to[i];
if(v==fa[now]) continue;
ha[(i+1)/2]=v;
update(1,n,1,w[v],val[i]);
build(v);
}
}
int main()
{
int a,b,c,op;
scanf("%d",&n);
for(int i=1;i<n;i++)
{
scanf("%d%d%d",&a,&b,&c);
a++;b++;
X[i]=a;Y[i]=b;Z[i]=c;
add(a,b,c);
add(b,a,c);
}
dfs(1);
getid(1,1);
build(1);
scanf("%d",&m);
char st[10];
while(m--)
{
scanf("%s",st);
if(st[0]=='C')
{
scanf("%d%d",&a,&b);
update(1,n,1,w[ha[a]],b);
}
if(st[0]=='N')
{
scanf("%d%d",&a,&b);
a++;b++;
getans3(a,b);
}
if(st[0]=='S')
{
scanf("%d%d",&a,&b);
a++;b++;
printf("%d\n",getans2(a,b));
}
if(st[0]=='M'&&st[1]=='A')
{
scanf("%d%d",&a,&b);
a++;b++;
printf("%d\n",getans1(a,b));
}
if(st[0]=='M'&&st[1]=='I')
{
scanf("%d%d",&a,&b);
a++;b++;
printf("%d\n",getans4(a,b));
}
}
return 0;
}
/*
5
0 1 1
1 2 1
0 3 1
3 4 1
7
MAX 2 4
MIN 2 4
SUM 2 4
C 1 2
MAX 2 4
MIN 2 4
SUM 2 4
*/