【POJ3237】Tree-树链剖分
来源:互联网 发布:骰子模拟器 mac版 编辑:程序博客网 时间:2024/06/10 08:37
题目大意:有一棵树,每条边有边权,有两种操作:1.修改某条边的边权。2.将某两个点之间路径上所有边的边权修改成它的相反数。3.询问某两个点之间路径上的所有边的边权的最大值。对于每个询问,给出正确的答案。
做法:一道比较难的树链剖分题,需要注意的是,在用线段树维护时,需要多维护一个区间最小值,因为在取反时,最大值和最小值会互换。
以下是本人代码:
#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>#define inf 999999999using namespace std;int t,n,tot,f[10010],siz[10010],dep[10010],pos[10010],p,a,b,c;int d[10010][3],first[10010],son[10010],top[10010],root;int qpos[10010];char op[10];struct edge{ int v,next;}e[20010];int seg[40010],m[40010],segp[40010]; //seg:区间最大值,m:区间最小值,segp:取反标记void readin(int a,int b,int c){ e[++tot].v=b; e[tot].next=first[a]; first[a]=tot;}void dfs1(int now){ siz[now]=1;son[now]=0; for(int i=first[now];i>0;i=e[i].next) if (e[i].v!=f[now]){ dep[e[i].v]=dep[now]+1; f[e[i].v]=now; dfs1(e[i].v); siz[now]+=siz[e[i].v]; if (siz[e[i].v]>siz[son[now]]) son[now]=e[i].v;}}void dfs2(int now,int chain){ pos[now]=++p;top[now]=chain; if (son[now]) dfs2(son[now],chain); for(int i=first[now];i>0;i=e[i].next) if (e[i].v!=f[now]&&e[i].v!=son[now]) dfs2(e[i].v,e[i].v);}void pushdown(int no){ if (segp[no]==-1) { int t;t=seg[no<<1];seg[no<<1]=-m[no<<1];m[no<<1]=-t;t=seg[(no<<1)+1];seg[(no<<1)+1]=-m[(no<<1)+1];m[(no<<1)+1]=-t;segp[no]=1;segp[no<<1]=-segp[no<<1];segp[(no<<1)+1]=-segp[(no<<1)+1]; }}void pushup(int no){ seg[no]=max(seg[no<<1],seg[(no<<1)+1]); m[no]=min(m[no<<1],m[(no<<1)+1]);}void buildtree(int no,int l,int r){ int mid=(l+r)>>1; segp[no]=1; if (l==r) {seg[no]=d[qpos[l]][2];m[no]=seg[no];return;} buildtree(no<<1,l,mid); buildtree((no<<1)+1,mid+1,r); pushup(no);}void change(int no,int l,int r,int a,int c){ int mid=(l+r)>>1; if (l==r) {seg[no]=c;m[no]=c;return;} pushdown(no); if (a<=mid) change(no<<1,l,mid,a,c); else change((no<<1)+1,mid+1,r,a,c); pushup(no);}int querymx(int no,int l,int r,int s,int t){ int mid=(l+r)>>1; if (l>=s&&r<=t) return seg[no]; int mx=-inf; pushdown(no); if (s<=mid) mx=max(mx,querymx(no<<1,l,mid,s,t)); if (t>mid) mx=max(mx,querymx((no<<1)+1,mid+1,r,s,t)); pushup(no); return mx;}void neg(int no,int l,int r,int s,int t){ int mid=(l+r)/2; if (l>=s&&r<=t) { segp[no]=-segp[no];int tmp=seg[no];seg[no]=-m[no];m[no]=-tmp;return; } pushdown(no); if (s<=mid) neg(no<<1,l,mid,s,t); if (t>mid) neg((no<<1)+1,mid+1,r,s,t); pushup(no);}int query(int a,int b){ int mx=-inf; while(top[a]!=top[b]) { if (dep[top[a]]<dep[top[b]]) swap(a,b);mx=max(mx,querymx(1,1,p,pos[top[a]],pos[a]));a=f[top[a]]; } if (dep[a]<dep[b]) swap(a,b); if (a!=b) mx=max(mx,querymx(1,1,p,pos[son[b]],pos[a])); return mx;}void nega(int a,int b){ while(top[a]!=top[b]) { if (dep[top[a]]<dep[top[b]]) swap(a,b);neg(1,1,p,pos[top[a]],pos[a]);a=f[top[a]]; } if (dep[a]<dep[b]) swap(a,b); if (a!=b) neg(1,1,p,pos[son[b]],pos[a]);}void read(){ op[0]=' '; while (op[0]<'C'||op[0]>'Q') scanf("%s",op);}void input(){ scanf("%d",&n); root=1; memset(first,0,sizeof(first)); memset(seg,0,sizeof(seg)); memset(m,0,sizeof(m)); tot=f[root]=dep[root]=p=0; for(int i=1;i<=n-1;i++) { scanf("%d %d %d",&a,&b,&c);d[i][0]=a;d[i][1]=b;d[i][2]=c;readin(a,b,c);readin(b,a,c); } dfs1(root); dfs2(root,root); for(int i=1;i<n;i++) {if (dep[d[i][0]]>dep[d[i][1]]) swap(d[i][0],d[i][1]);qpos[pos[d[i][1]]]=i; } buildtree(1,1,p);}void work(){ int a,b; for(read();op[0]!='D';read()) { scanf("%d %d",&a,&b); if (op[0]=='Q') printf("%d\n",query(a,b));else if (op[0]=='C') change(1,1,p,pos[d[a][1]],b); else nega(a,b); }}int main(){ for(scanf("%d",&t);t>0;t--) { input();work(); } return 0;}
0 0
- 【POJ3237】Tree 树链剖分
- poj3237 Tree 树链剖分
- poj3237 Tree [树链剖分]
- 【POJ3237】Tree(树链剖分)
- 【POJ3237】Tree-树链剖分
- POJ3237 Tree【树链剖分】
- poj3237 Tree(树链剖分)
- poj3237--Tree(树链剖分+线段树)
- 树链剖分+线段树 poj3237 Tree
- poj3237 Tree
- 【poj3237】 Tree
- poj3237 Tree
- POJ3237:Tree
- 【poj3237】Tree
- POJ3237 Tree
- poj3237 Tree
- poj3237 Tree
- poj3237 树链剖分
- 控制物体随鼠标旋转
- freemarker页面如何获取绝对路径basePath
- php://input,$_POST,$HTTP_RAW_POST_DATA区别
- iOS常用的一些第三方
- iOS-UIDevice
- 【POJ3237】Tree-树链剖分
- 【华为 OJ】 字符串反转
- 在android studio导入项目报错-buildtool版本错误
- 虎牙和yy什么关系
- 去掉导航栏下面的线iOS
- Macbook Intellij idea与Eclipse远程调试Hadoop应用程序
- 数据结构与二维数组 json、xml
- HDU-1596 find the safest road 【最远路】
- 【华为 OJ】 句子逆序