树链剖分+线段树 POJ3237 权值在边 模板
来源:互联网 发布:公司屏蔽了淘宝怎么办 编辑:程序博客网 时间:2024/05/18 04:00
#include<stdio.h>#include<string.h>#include<stdlib.h>#include<iostream>#include<algorithm>#include<vector>#include<queue>#include<map>#include<math.h>using namespace std;const int maxn=100010;struct Edge{ int to; int next;}edge[maxn*2];int head[maxn],tot;int top[maxn];//top[v]表示v所在的重链的顶端节点int fa[maxn];//父亲节点int deep[maxn];//深度int num[maxn];//num[v]表示以v为根的子树的节点数int p[maxn];//p[v]表示v与其父亲节点的连边在线段树中的位置int fp[maxn];//和p数组相反int son[maxn];//重儿子int pos;int e[maxn][3];void init(){ tot=0; memset(head,-1,sizeof(head)); pos=0; memset(son,-1,sizeof(son));}void add(int u,int v){ edge[tot].to=v; edge[tot].next=head[u]; head[u]=tot++;}void dfs1(int u,int father,int dep)//第一遍dfs求出fa,deep,num,son{ deep[u]=dep; fa[u]=father; num[u]=1; for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].to; if(v!=father) { dfs1(v,u,dep+1); num[u]+=num[v]; if(son[u]==-1||num[son[u]]<num[v]) son[u]=v; } }}void dfs2(int u,int tp)//第二遍dfs求出top和p{ top[u]=tp; p[u]=pos++; fp[p[u]]=u; if(son[u]==-1) return; dfs2(son[u],tp); for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].to; if(v!=fa[u]&&v!=son[u]) dfs2(v,v); }}struct node{ int l,r,maxx,minn,nege;}q[maxn*3];void build(int i,int l,int r){ q[i].l=l; q[i].r=r; q[i].maxx=q[i].minn=q[i].nege=0; if(l==r) return; int mid=(l+r)/2; build(i*2,l,mid); build(i*2+1,mid+1,r);}void pushup(int i){ q[i].maxx=max(q[i*2].maxx,q[i*2+1].maxx); q[i].minn=min(q[i*2].minn,q[i*2+1].minn);}void pushdown(int i){ if(q[i].l==q[i].r) return; if(q[i].nege) { q[i*2].maxx=-q[i*2].maxx; q[i*2].minn=-q[i*2].minn; swap(q[i*2].maxx,q[i*2].minn); q[i*2+1].maxx=-q[i*2+1].maxx; q[i*2+1].minn=-q[i*2+1].minn; swap(q[i*2+1].maxx,q[i*2+1].minn); q[i*2].nege^=1; q[i*2+1].nege^=1; q[i].nege=0; }}void update(int i,int k,int val)// 更新线段树的第k个值为val{ if(q[i].l==k&&q[i].r==k) { q[i].maxx=val; q[i].minn=val; q[i].nege=0; return; } pushdown(i); int mid=(q[i].l+q[i].r)/2; if(k<=mid) update(i*2,k,val); else update(i*2+1,k,val); pushup(i);}int query(int i,int l,int r)//查询线段树中[l,r] 的最大值{ if(q[i].l==l&&q[i].r==r) { return q[i].maxx; } pushdown(i); int mid=(q[i].l+q[i].r)/2; if(r<=mid) return query(i*2,l,r); else if(l>mid) return query(i*2+1,l,r); else { return max(query(i*2,l,mid),query(i*2+1,mid+1,r)); } pushup(i);}int findmax(int u,int v)//查询u->v边的最大值{ int f1=top[u]; int f2=top[v]; int tmp=-100000000; while(f1!=f2) { if(deep[f1]<deep[f2]) { swap(f1,f2); swap(u,v); } tmp=max(tmp,query(1,p[f1],p[u])); u=fa[f1]; f1=top[u]; } if(u==v) return tmp; if(deep[u]>deep[v]) swap(u,v); return max(tmp,query(1,p[son[u]],p[v]));}void Negate1(int i,int l,int r)// 更新线段树的区间[l,r]取反{ if(q[i].l==l&&q[i].r==r) { q[i].maxx=-q[i].maxx; q[i].minn=-q[i].minn; swap(q[i].maxx,q[i].minn); q[i].nege^=1; return; } pushdown(i); int mid=(q[i].l+q[i].r)/2; if(r<=mid) Negate1(i*2,l,r); else if(l>mid) Negate1(i*2+1,l,r); else { Negate1(i*2,l,mid); Negate1(i*2+1,mid+1,r); } pushup(i);}void Negate(int u,int v)//把u-v路径上的边的值都设置为val{ int f1=top[u]; int f2=top[v]; while(f1!=f2) { if(deep[f1]<deep[f2]) { swap(f1,f2); swap(u,v); } Negate1(1,p[f1],p[u]); u=fa[f1]; f1=top[u]; } if(u==v) return; if(deep[u]>deep[v]) swap(u,v); return Negate1(1,p[son[u]],p[v]);}int main(void){ int i,j,k,t,n; scanf("%d",&t); while(t--) { init(); scanf("%d",&n); for(i=0;i<n-1;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,0); dfs2(1,1); build(1,0,pos-1); for(i=0;i<n-1;i++) { if(deep[e[i][0]]>deep[e[i][1]]) swap(e[i][0],e[i][1]); update(1,p[e[i][1]],e[i][2]); } char op[10]; int x,y; while(scanf("%s",op)!=EOF) { if(op[0]=='D') break; scanf("%d%d",&x,&y); if(op[0]=='Q') printf("%d\n",findmax(x,y));//查询x->y路径上边权的最大值 else if(op[0]=='C') update(1,p[e[x-1][1]],y);//改变第x条边的值为y else Negate(x,y); } } return 0;}
阅读全文
0 0
- 树链剖分+线段树 POJ3237 权值在边 模板
- POJ3237 树链剖分+线段树
- 【POJ3237】Tree(树链剖分+线段树(基于边权))
- poj3237 树链部分 边权模板
- poj3237--Tree(树链剖分+线段树)
- 树链剖分+线段树 poj3237 Tree
- 树链剖分+线段树 HDU3966 权值在点 模板
- poj3237(树链剖分边维护+线段树区间更新)
- poj3237 树链剖分
- poj3237 树链剖分
- 树链剖分 POJ3237
- poj3237 树链剖分
- POJ3237树链剖分
- 模板 权值线段树
- 【POJ3237】Tree 树链剖分
- poj3237 Tree 树链剖分
- poj3237 Tree [树链剖分]
- 【POJ3237】Tree(树链剖分)
- leetcode 3. Longest Substring Without Repeating Characters
- map常用操作——添入、删除、查找、遍历
- python处理csv文件
- 条件化的Bean——@Conditional注解
- springboot访问jsp页面
- 树链剖分+线段树 POJ3237 权值在边 模板
- oracle rac增加节点报错三例
- 如何解决Android虚拟按键_类似华为的虚拟键
- 如何发布自己的 jar 包到 maven 中央仓库
- 靶形数独(dfs+剪枝)
- JSP交互---JSTL标签
- ST17H26程序移植关键部分记录
- 百度地图JavaScript开发入门教程
- HDOJ2048_神、上帝以及老天爷