POJ 3237 Tree 树链剖分 边权
来源:互联网 发布:宏杰软件 编辑:程序博客网 时间:2024/06/04 19:39
这个题目比SPOJ的QTree多了一个u->v内所有边的边权都变为相反数的操作,其他的都是类似的,单点更新,区间查询最大值。
因为有了取反操作,因为最小值的相反数是最大值,最大值的相反数是最小值..所以线段树要多记录一个最小值...
用这个题的代码我过了SPOJ那个QTREE,当时那个RE错误..并不懂是怎么犯的..
#include<iostream>#include<algorithm>#include<cstdlib>#include<cstring>#include<cmath>#include<cstdio>using namespace std;#define MAXN 10010struct 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;}
0 0
- POJ 3237 Tree 树链剖分 边权
- POJ 3237 Tree 树链剖分
- 【POJ】3237 Tree 树链剖分
- POJ 3237 Tree 树链剖分
- 【树链剖分】 POJ 3237 Tree
- poj 3237 Tree(树链剖分)
- POJ 3237 Tree (树链剖分)
- POJ 3237 Tree 树链剖分
- POJ 3237 Tree 树链剖分
- poj 3237 Tree 树链剖分
- poj 3237 Tree 树链剖分
- POJ 3237 - Tree(树链剖分)
- poj 3237 Tree 树链剖分
- POJ 3237Tree 树链剖分
- POJ 3237 Tree 树链剖分
- POJ-3237Tree(树链剖分)
- POJ 3237 Tree(树链剖分——边权)
- poj 3237 Tree(树链剖分)
- HDU 1423 Greatest Common Increasing Subsequence
- HDU 1873 看病要排队 优先队列
- UI_UITableView _新知识_02
- 模板-最小生成树计数
- bzoj1375[Baltic2002]Bicriterial routing 双调路径
- POJ 3237 Tree 树链剖分 边权
- C++Primer第五版 7.5.2节练习
- Pro/E环境下的弧齿锥齿轮三维参数化造型
- 视频编解码学习之一:理论基础
- PHP中静态(static)调用非静态方法详解
- C++Primer第五版 7.5.3节练习
- ARM7学习笔记——中断向量控制器VIC
- Camora调用系统的照相机和相册以及图片的压缩
- 关于多个spinner联动