SPOJ QTREEQuery on a tree(树链剖分-点更新-区间最值查询-入边)
来源:互联网 发布:dotnet可以用java吗 编辑:程序博客网 时间:2024/06/12 03:46
题意:
操作1.更改第i条边权值
操作2.查询i->j的路径最大值
操作3 跳出
#include <cstdio>#include <cstring>#include <vector>#include <algorithm>using namespace std;const int maxn = 100005;int dep[maxn],siz[maxn],fa[maxn],id[maxn],son[maxn],val[maxn],top[maxn];int topw,head[maxn],cnt;///dep 深度 siz个数 fa父 top祖 son重儿子 val值/// e数组 初始入边 edge数组存边struct Edge{ int to,next;} edge[maxn*2];struct treex{ int x,y,val;} e[maxn];void add(int u,int v ){ edge[cnt].to=v; edge[cnt].next=head[u]; head[u]=cnt++;}void dfs1(int u,int f,int d){ dep[u]=d; siz[u]=1; son[u]=0; fa[u]=f; for(int i =head[u];i!=-1;i=edge[i].next) { int v=edge[i].to; if(v==fa[u]) continue; dfs1(v,u,d+1); siz[u]+=siz[v]; if(siz[son[u]]<siz[v]) son[u]=v; }}void dfs2(int u,int tp){ top[u]=tp; id[u]=++topw; if(son[u]) 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]) continue; dfs2(v,v); }}struct node{ int left,right,maxx;}tree[maxn*4];void push_up(int i){ tree[i].maxx=max(tree[i<<1].maxx,tree[i<<1|1].maxx);}void build(int i,int left,int right){ tree[i].left=left; tree[i].right=right; if(left==right) { tree[i].maxx=val[left]; return ; } int mid=(tree[i].left+tree[i].right)>>1; build(i<<1,left,mid); build(i<<1|1,mid+1,right); push_up(i);}void update(int i,int aim,int w){ if(tree[i].left==tree[i].right&&tree[i].left==aim) { tree[i].maxx=w; return ; } int mid=(tree[i].left+tree[i].right)>>1; if(aim<=mid) update(i<<1,aim,w); else update(i<<1|1,aim,w); push_up(i);}int query(int i,int left,int right){ if(tree[i].left>=left&&tree[i].right<=right) return tree[i].maxx; int mid=(tree[i].left+tree[i].right)>>1; if(right<=mid) return query(i<<1,left,right); else if(left>mid) return query(i<<1|1,left,right); else return max(query(i<<1,left,mid),query(i<<1|1,mid+1,right));}int change(int u,int v){ int tpu=top[u],tpv=top[v]; int ans=0; while(tpu!=tpv) { if(dep[tpu]<dep[tpv]) swap(u,v),swap(tpu,tpv); ans=max(ans,query(1,id[tpu],id[u])); u=fa[tpu]; tpu=top[u]; } if(u!=v) { if(dep[u]>dep[v]) swap(u,v); ans=max(ans,query(1,id[son[u]],id[v])); } return ans;}int main(){ int n,m,s; int t; scanf("%d",&t); while(t--) { scanf("%d",&n); memset(head,-1,sizeof(head)); for(int i=1;i<n;i++) { scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].val); add(e[i].x,e[i].y); add(e[i].y,e[i].x); } topw=0; dfs1(1,0,1); dfs2(1,1); //将之前给出的边的权值,赋给点。 for(int i=1;i<n;i++) { if(dep[e[i].x] < dep[e[i].y]) swap(e[i].x,e[i].y); val[id[e[i].x]] = e[i].val; } char op[10]; build(1,1,topw); while(1) { scanf("%s",op); if(op[0]=='Q') { int l,r; scanf("%d%d",&l,&r); printf("%d\n",change(l,r)); } else if(op[0]=='C') { int x,y; scanf("%d%d",&x,&y); update(1,id[e[x].x],y); } else break; } } return 0;}
阅读全文
0 0
- SPOJ QTREEQuery on a tree(树链剖分-点更新-区间最值查询-入边)
- SPOJ QTREEQuery on a tree
- POJ 3237Tree(树链剖分-线段树点更新-区间更新-区间最值查询-入边)
- 树链剖分模板题-SPOJ QTREEQuery on a tree
- POJ 2763Housewife Wind(树链剖分+线段树点更新-区间查询+入边)
- SPOJ 题目913QTREE2 - Query on a tree II(Link Cut Tree 查询路径第k个点)
- [SPOJ 375]Query On a Tree(树链剖分)
- SPOJ 375. Query on a tree【树链剖分】
- SPOJ 375. Query on a tree【树链剖分】
- SPOJ QTREE(Query on a tree树链剖分)
- spoj 375--Query On a Tree [树链剖分]
- spoj 375 Query on a tree 树链剖分
- spoj 375. Query on a tree(树链剖分)
- SPOJ QTREE Query on a tree --树链剖分
- [ SPOJ - QTREE]Query on a tree && 树链剖分
- SPOJ Query on a tree (树链剖分)
- SPOJ QTREE Query on a tree 树链剖分
- SPOJ QTREE Query on a tree 树链剖分
- Angular 4 新特性给响应式编程带来的好处
- iOS的阴影绘制及性能优化
- Java IO流
- SQL Server数据库备份还原时,提示“数据库正在使用”的解决办法
- tomcat的session冲突
- SPOJ QTREEQuery on a tree(树链剖分-点更新-区间最值查询-入边)
- 关于“keyup”的使用
- 不依赖数组(字符串版)
- ApplicationContext 、WebApplicationContext、ContextLoaderListener
- 【LeetCode】575. Distribute Candies
- 剑指offer-二叉树的深度
- C# 装箱,拆箱,向上转型,向下转型
- Terrible Sets POJ
- redis的安装