SPOJ QTREEQuery on a tree
来源:互联网 发布:iwatch软件排行 编辑:程序博客网 时间:2024/05/21 10:45
链接:http://acm.hust.edu.cn/vjudge/contest/28982#problem/I
题意:给定一棵n个节点的树,操作A:修改边权,操作B:询问u->v路径上的最大边权。
分析:树链剖分边权练习题,因为是边权而询问是点我们把边权落在节点上,那么我们在询问时是不能计算lca的那个节点的,我是先求了下lca然后将每次在线段是上找时都处理下要大于lca的编号。
代码:
#include<map>#include<set>#include<cmath>#include<queue>#include<bitset>#include<math.h>#include<vector>#include<string>#include<stdio.h>#include<cstring>#include<iostream>#include<algorithm>#pragma comment(linker, "/STACK:102400000,102400000")using namespace std;const int N=10010;const int mod=998244353;const int MOD1=1000000007;const int MOD2=1000000009;const double EPS=0.00000001;typedef long long ll;const ll MOD=1000000007;const int INF=1000000010;const ll MAX=1ll<<55;const double eps=1e-5;const double inf=~0u>>1;const double pi=acos(-1.0);typedef double db;typedef unsigned long long ull;int tot,u[N],v[2*N],w[2*N],pre[2*N];void add(int a,int b,int c) { v[tot]=b;w[tot]=c;pre[tot]=u[a];u[a]=tot++; v[tot]=a;w[tot]=c;pre[tot]=u[b];u[b]=tot++;}int n,c[N],f[N],d[N],g[N],h[N];int fa[N],dep[N],siz[N],son[N],top[N];void dfs1(int a,int b,int c) { dep[a]=dep[b]+1;son[a]=0; fa[a]=b;siz[a]=1;d[c]=a;h[a]=c; int i,mx=0; for (i=u[a];i!=-1;i=pre[i]) if (v[i]!=b) { dfs1(v[i],a,w[i]);siz[a]+=siz[v[i]]; if (siz[v[i]]>mx) son[a]=v[i],mx=siz[v[i]]; }}void dfs2(int a,int b) { if (son[b]==a) top[a]=top[b]; else top[a]=a; f[a]=++tot;g[tot]=c[h[a]]; if (son[a]) dfs2(son[a],a); for (int i=u[a];i!=-1;i=pre[i]) if (v[i]!=b&&v[i]!=son[a]) dfs2(v[i],a);}char s[10];int mx[N<<2];void build(int x,int l,int r) { if (l==r) { mx[x]=g[l];return ; } int mid=(l+r)>>1; build(x<<1,l,mid);build(x<<1|1,mid+1,r); mx[x]=max(mx[x<<1],mx[x<<1|1]);}int getmax(int x,int l,int r,int L,int R) { if (L>R) return 0; if (l==L&&r==R) return mx[x]; int mid=(l+r)>>1; if (R<=mid) return getmax(x<<1,l,mid,L,R); else if (L>mid) return getmax(x<<1|1,mid+1,r,L,R); else return max(getmax(x<<1,l,mid,L,mid),getmax(x<<1|1,mid+1,r,mid+1,R));}int lca(int a,int b) { int f1=top[a],f2=top[b]; while (f1!=f2) { if (dep[f1]<dep[f2]) swap(a,b),swap(f1,f2); a=fa[f1];f1=top[a]; } if (dep[a]<dep[b]) swap(a,b); return b;}int query(int a,int b) { int i,ret=0,f1=top[a],f2=top[b],mi=f[lca(a,b)]+1; while (f1!=f2) { if (dep[f1]<dep[f2]) swap(a,b),swap(f1,f2); ret=max(ret,getmax(1,1,n,max(f[f1],mi),f[a])); a=fa[f1];f1=top[a]; } if (dep[a]<dep[b]) swap(a,b); return max(ret,getmax(1,1,n,max(f[b],mi),f[a]));}void updata(int x,int l,int r,int y,int z) { if (l==r) { mx[x]=z;return ; } int mid=(l+r)>>1; if (y<=mid) updata(x<<1,l,mid,y,z); else updata(x<<1|1,mid+1,r,y,z); mx[x]=max(mx[x<<1],mx[x<<1|1]);}int main(){ int a,b,i,t; scanf("%d", &t); while (t--) { scanf("%d", &n); tot=0;memset(u,-1,sizeof(u)); for (i=1;i<n;i++) { scanf("%d%d%d", &a, &b, &c[i]);add(a,b,i); } dfs1(1,0,0);tot=0;dfs2(1,0); build(1,1,n); while (scanf("%s", s)) { if (s[0]=='D') break ; scanf("%d%d", &a, &b); if (s[0]=='Q') printf("%d\n", query(a,b)); else updata(1,1,n,f[d[a]],b); } } return 0;}
0 0
- SPOJ QTREEQuery on a tree
- 树链剖分模板题-SPOJ QTREEQuery on a tree
- SPOJ QTREEQuery on a tree(树链剖分-点更新-区间最值查询-入边)
- SPOJ Query on a tree
- SPOJ Count on a tree
- SPOJ Query on a tree
- Count on a tree SPOJ
- SPOJ Query on a tree
- Count on a tree SPOJ
- Query on a tree SPOJ
- Query on a tree SPOJ
- [SPOJ 375]Query On a Tree(树链剖分)
- SPOJ 375. Query on a tree【树链剖分】
- SPOJ 375. Query on a tree【树链剖分】
- spoj cot Count on a tree
- SPOJ QTREE(Query on a tree树链剖分)
- spoj 10628 Count on a tree
- SPOJ 375.Query on a tree
- 广度优先搜索双队列通用编程模板
- hdu 5823 color II 状压dp 图的色数
- bat执行java小实例
- 回车”(Carriage Return)和“换行”(Line Feed)起源
- Android Studio中如何使用Git和Github来管理项目
- SPOJ QTREEQuery on a tree
- 程序员修炼之道-从小工到专家读后感
- Map方法获取默认值
- 单点登录限制下暴露的新漏洞及规避方法
- intellij idea入门,基础功能介绍
- 自定义ViewPager XML文件无法识别问题
- QuotedString 和 UnquotedString 区别
- Koa vs Express
- android 接口回调