维护边上信息的树链剖分,
我是将父边的信息储存在结点上,
然后按与维护点值类似方法处理的。
注意本题有多组数据,对于每组数据,
树上信息和线段树一定要重新赋值!!!
本蒟蒻因此WA了好多次。。。。。。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define Mp(x,y) std::make_pair(x,y)
const int MAXN = 1e5+5, INF = 1e9;
struct Edge{int v,w,next; Edge(int v = 0,int w = 0,int next = 0):v(v),w(w),next(next){}};
int n , m;
int head[MAXN] = {0}, el = 0;
Edge edge[MAXN<<1] = {0};
int fa[MAXN] = {0},size[MAXN] = {0},dep[MAXN] = {0};
int top[MAXN] = {0},son[MAXN] = {0};
int fc[MAXN] = {0} ,dl = 0, nfc[MAXN] = {0};
int efc[MAXN] = {0}, fe[MAXN] = {0};
namespace seg
{
#define L(x) (x<<1)
#define R(x) ((x<<1)|1)
struct TreeNode{int max,min,tag;};
int value;
TreeNode tree[MAXN<<2] = {0};
void PushDown(int x)
{
if(tree[x].tag)
{
std::swap(tree[L(x)].max,tree[L(x)].min);
tree[L(x)].max*=-1,tree[L(x)].min*=-1;
std::swap(tree[R(x)].max,tree[R(x)].min);
tree[R(x)].max*=-1,tree[R(x)].min*=-1;
tree[L(x)].tag ^= 1, tree[R(x)].tag ^= 1;
tree[x].tag = 0;
}
}
void Update(int x)
{
tree[x].max = std::max(tree[L(x)].max,tree[R(x)].max);
tree[x].min = std::min(tree[L(x)].min,tree[R(x)].min);
}
void Build(int ll,int rr,int si)
{
tree[si].tag = 0;
if(ll == rr)
tree[si].max = tree[si].min = edge[fe[nfc[ll]]].w;
else
{
int mid = (ll + rr) >>1;
if(ll <= mid)Build(ll,mid,L(si));
if(mid < rr)Build(mid+1,rr,R(si));
Update(si);
}
}
void Change(int ll,int rr,int l,int r,int si)
{
if(ll == l && rr == r)
tree[si].max = tree[si].min = value;
else
{
PushDown(si);
int mid = (ll+rr)>>1;
if(r <= mid)
Change(ll,mid,l,r,L(si));
else if(mid < l)
Change(mid+1,rr,l,r,R(si));
else
{
Change(ll,mid,l,mid,L(si));
Change(mid+1,rr,mid+1,r,R(si));
}
Update(si);
}
}
void Color(int ll,int rr,int l,int r,int si)
{
if(ll == l && rr == r)
{
tree[si].tag ^= 1;
std::swap(tree[si].max,tree[si].min);
tree[si].max*=-1,tree[si].min*=-1;
}
else
{
PushDown(si);
int mid = (ll+rr)>>1;
if(r <= mid)
Color(ll,mid,l,r,L(si));
else if(mid < l)
Color(mid+1,rr,l,r,R(si));
else
{
Color(ll,mid,l,mid,L(si));
Color(mid+1,rr,mid+1,r,R(si));
}
Update(si);
}
}
int Query(int ll,int rr,int l,int r,int si)
{
if(ll == l && rr == r)
return tree[si].max;
else
{
PushDown(si);
int mid = (ll+rr)>>1;
if(r <= mid)
return Query(ll,mid,l,r,L(si));
else if(mid < l)
return Query(mid+1,rr,l,r,R(si));
else
{
int ret1, ret2;
ret1 = Query(ll,mid,l,mid,L(si));
ret2 = Query(mid+1,rr,mid+1,r,R(si));
return std::max(ret1,ret2);
}
Update(si);
}
}
#undef L
#undef R
}
void NewEdge(int u,int v,int w)
{++el; edge[el] = Edge(v,w,head[u]); head[u] = el;}
void Clear()
{el = dl = 0; for(int i = 1; i <= n; i++) fa[i] = head[i] = 0;}
void Change(int p,int x)
{
seg::value = x; seg::Change(1,n,p,p,1);
}
void Negate(int x,int y)
{
while(top[x] != top[y])
{
if(dep[top[x]] > dep[top[y]])
std::swap(x,y);
seg::Color(1,n,fc[top[y]],fc[y],1);
y = fa[top[y]];
}
if(x != y)
{
if(dep[x] > dep[y]) std::swap(x,y);
seg::Color(1,n,fc[son[x]],fc[y],1);
}
}
int Query(int x,int y)
{
int ret = -INF;
while(top[x] != top[y])
{
if(dep[top[x]] > dep[top[y]])
std::swap(x,y);
int tmp = seg::Query(1,n,fc[top[y]],fc[y],1);
ret = std::max(ret,tmp);
y = fa[top[y]];
}
if(x != y)
{
if(dep[x] > dep[y]) std::swap(x,y);
int tmp = seg::Query(1,n,fc[son[x]],fc[y],1);
ret = std::max(ret,tmp);
}
return ret;
}
void DFS(int a)
{
dep[a] = dep[fa[a]] + 1;
size[a] = 1, son[a] = 0;
for(int i = head[a]; i ; i = edge[i].next)
{
int p = edge[i].v;
if(p == fa[a])continue;
efc[(i+(i&1))>>1] = p;
fa[p] = a, fe[p] = i;
DFS(p);
size[a] += p;
if(size[p] > size[son[a]])
son[a] = p;
}
}
void Build(int a)
{
nfc[++dl] = a, fc[a] = dl;
top[a] = a;
if(son[fa[a]] == a)
top[a] = top[fa[a]];
if(son[a]) Build(son[a]);
for(int i = head[a]; i ; i = edge[i].next)
{
int p = edge[i].v;
if(p == fa[a] || p == son[a])continue;
Build(p);
}
}
int main()
{
int T;
#ifndef ONLINE_JUDGE
freopen("poj3237.in","r",stdin);
freopen("poj3237.out","w",stdout);
#endif
std::cin >> T;
while(T--)
{
std::cin >> n; Clear();
for(int i = 1,a,b,w; i < n; i++)
{
scanf("%d%d%d",&a,&b,&w);
NewEdge(a,b,w);NewEdge(b,a,w);
}
DFS(1); Build(1); seg::Build(1,n,1);
bool flag = true;
while(flag)
{
char str[10];int a , b;
scanf("%s",str);
switch(str[0])
{
case 'D':
flag = false;
break;
case 'C':
scanf("%d%d",&a,&b);
Change(fc[efc[a]],b);
break;
case 'N':
scanf("%d%d",&a,&b);
Negate(a,b);
break;
case 'Q':
scanf("%d%d",&a,&b);
printf("%d\n",Query(a,b));
break;
}
}
}
#ifndef ONLINE_JUDGE
fprintf(stderr,"%f",clock()*1.0/CLOCKS_PER_SEC);
fclose(stdin);
fclose(stdout);
#endif
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。