您的位置:首页 > 其它

POJ 3237 Tree 树链剖分 边权

2015-09-15 20:08 316 查看
这个题目比SPOJ的QTree多了一个u->v内所有边的边权都变为相反数的操作,其他的都是类似的,单点更新,区间查询最大值。

因为有了取反操作,因为最小值的相反数是最大值,最大值的相反数是最小值..所以线段树要多记录一个最小值...

用这个题的代码我过了SPOJ那个QTREE,当时那个RE错误..并不懂是怎么犯的..

#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<cstdio>
using namespace std;
#define MAXN 10010

struct edge
{
int u,v,next;
}edge[MAXN*2];
int son[MAXN],fa[MAXN],top[MAXN],num[MAXN];
int dep[MAXN],p[MAXN],head[MAXN];
int t,pos;
void inti()
{
t=0;
memset(head,-1,sizeof(head));
pos=1;
memset(son,-1,sizeof(son));
}
void add(int u,int v)
{
edge[t].v=v;
edge[t].next=head[u];
head[u]=t++;
}
void dfs1(int u,int d)
{
dep[u]=d;
num[u]=1;
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].v;
if(v!=fa[u])
{
fa[v]=u;
dfs1(v,d+1);
num[u]+=num[v];
if(son[u]==-1||num[v]>num[son[u]])
son[u]=v;
}
}
}
void dfs2(int u,int sp)
{
top[u]=sp;
p[u]=pos++;
if(son[u]!=-1)
dfs2(son[u],sp);
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].v;
if(v!=son[u]&&v!=fa[u])
dfs2(v,v);
}
}

struct node
{
int l,r,ma,mi,ne;
}data[MAXN*4];
void build(int l,int r,int k)
{
data[k].l=l;
data[k].r=r;
data[k].ma=data[k].mi=0;
data[k].ne=0;
if(l==r) return ;
int mid=(l+r)/2;
build(l,mid,k*2);
build(mid+1,r,k*2+1);
}
void pushup(int k)
{
data[k].ma=max(data[k*2].ma,data[k*2+1].ma);
data[k].mi=min(data[k*2].mi,data[k*2+1].mi);
}
void pushdown(int k)
{
if(data[k].l==data[k].r) return ;
if(data[k].ne)
{
data[k*2].ma=-data[k*2].ma;
data[k*2].mi=-data[k*2].mi;
swap(data[k*2].ma,data[k*2].mi);
data[k*2+1].ma=-data[k*2+1].ma;
data[k*2+1].mi=-data[k*2+1].mi;
swap(data[k*2+1].ma,data[k*2+1].mi);
data[k*2].ne^=1;
data[k*2+1].ne^=1;
data[k].ne=0;
}
}
void updata(int x,int val,int k)
{
if(data[k].l==data[k].r&&data[k].l==x)
{
data[k].ma=data[k].mi=val;
data[k].ne=0;
return ;
}
pushdown(k);
int mid=(data[k].l+data[k].r)/2;
if(x<=mid)
updata(x,val,k*2);
else
updata(x,val,k*2+1);
pushup(k);
}
void neupdata(int l,int r,int k)
{
if(data[k].l==l&&data[k].r==r)
{
data[k].ma=-data[k].ma;
data[k].mi=-data[k].mi;
swap(data[k].ma,data[k].mi);
data[k].ne^=1;
return ;
}
pushdown(k);
int mid=(data[k].l+data[k].r)/2;
if(r<=mid) neupdata(l,r,k*2);
else if(l>mid) neupdata(l,r,k*2+1);
else
{
neupdata(l,mid,k*2);
neupdata(mid+1,r,k*2+1);
}
pushup(k);
}
int query(int l,int r,int k)
{
if(data[k].l==l&&data[k].r==r)
return data[k].ma;
pushdown(k);
int mid=(data[k].l+data[k].r)/2;
if(r<=mid)
return query(l,r,k*2);
else if(l>mid)
return query(l,r,k*2+1);
else
return max(query(l,mid,k*2),query(mid+1,r,k*2+1));
}
int findmax(int u,int v)
{
int f1=top[u];
int f2=top[v];
int ans=-100000000;;
while(f1!=f2)
{
if(dep[f1]<dep[f2])
{
swap(f1,f2);
swap(u,v);
}
ans=max(ans,query(p[f1],p[u],1));
u=fa[f1];
f1=top[u];
}
if(u==v) return ans;
if(dep[u]>dep[v]) swap(u,v);
return  max(ans,query(p[son[u]],p[v],1));
}
void negat(int u,int v)
{
int f1=top[u];
int f2=top[v];
while(f1!=f2)
{
if(dep[f1]<dep[f2])
{
swap(f1,f2);
swap(u,v);
}
neupdata(p[f1],p[u],1);
u=fa[f1];
f1=top[u];
}
if(u==v) return ;
if(dep[u]>dep[v]) swap(u,v);
neupdata(p[son[u]],p[v],1);
}
int e[MAXN][3];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
inti();
scanf("%d",&n);
for(int i=1;i<n;i++)
{
scanf("%d %d %d",&e[i][0],&e[i][1],&e[i][2]);
add(e[i][0],e[i][1]);
add(e[i][1],e[i][0]);
}
dfs1(1,0);
dfs2(1,1);
build(1,pos,1);
for(int i=1;i<n;i++)
{
if(dep[e[i][0]]>dep[e[i][1]])
swap(e[i][0],e[i][1]);
updata(p[e[i][1]],e[i][2],1);
}
char op[10];
int u,v;
while(scanf("%s",op)==1)
{
if(op[0]=='D')
break;
scanf("%d %d",&u,&v);
if(op[0]=='Q')
printf("%d\n",findmax(u,v));
else if(op[0]=='C')
updata(p[e[u][1]],v,1);
else
negat(u,v);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: