POJ 3237 Tree 树链剖分 边权
2015-09-15 20:08
316 查看
这个题目比SPOJ的QTree多了一个u->v内所有边的边权都变为相反数的操作,其他的都是类似的,单点更新,区间查询最大值。
因为有了取反操作,因为最小值的相反数是最大值,最大值的相反数是最小值..所以线段树要多记录一个最小值...
用这个题的代码我过了SPOJ那个QTREE,当时那个RE错误..并不懂是怎么犯的..
因为有了取反操作,因为最小值的相反数是最大值,最大值的相反数是最小值..所以线段树要多记录一个最小值...
用这个题的代码我过了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; }
相关文章推荐
- UIPageControl
- 新安装Win10
- Ember copy array
- html初学-简介
- Jquery 写的注册判断
- 创建设备节点
- Camora调用系统的照相机和相册以及图片的压缩
- delphi编译选项
- 关于多个spinner联动
- PHP中静态(static)调用非静态方法详解
- 视频编解码学习之一:理论基础
- Pro/E环境下的弧齿锥齿轮三维参数化造型
- 模板-最小生成树计数
- Ubuntu 14.04出现“device not managed”错误及ubuntu可以ping通外网浏览器上不了网。
- bzoj1375[Baltic2002]Bicriterial routing 双调路径
- 抽象工厂
- UI_UITableView _新知识_02
- HDU 1423 Greatest Common Increasing Subsequence
- 数据结构_单链表的逆置
- HDU 1873 看病要排队 优先队列