标签:integer space uil main bit const nlogn inf put
You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, 3...N-1.
We will ask you to perfrom some instructions of the following form:
The first line of input contains an integer t, the number of test cases (t <= 20). t test cases follow.
For each test case:
There is one blank line between successive tests.
For each "QUERY" operation, write one integer representing its result.
Input: 1 3 1 2 1 2 3 2 QUERY 1 2 CHANGE 1 3 QUERY 1 2 DONE Output: 1 3
题意:给一棵树,边上有权值,多组询问,问任意两个路劲之间的最大边权,修改某一条边的权值。
分析:
线段树已经炉火纯青了,重新标号后,可以build操作,但是想着update更方便,也只是O(nlogn),差不了多少。
点权会容易操作的多,但是这里是边权,我就将线段树底层第一个点至为 -inf,然后按照顺序加上边的权值,边权就变成线段树里面的点权了。
#include <bits/stdc++.h> using namespace std; const int maxn=10005; vector <pair<int,int> > g[maxn]; int num; const int inf=1<<29; int id[maxn],deep[maxn],siz[maxn],son[maxn],fa[maxn]; int val[maxn],top[maxn]; struct Edge { int x,y,val; void read() { scanf("%d %d %d",&x,&y,&val); g[x].push_back(make_pair(y,val)); g[y].push_back(make_pair(x,val)); } }edges[maxn+20]; void dfs1(int u,int father,int d,int va) { deep[u]=d; siz[u]=1; son[u]=0; fa[u]=father; val[u] = va; for(int i=0;i<(int)g[u].size();i++) { int v=g[u][i].first; if(v==father) continue; dfs1(v,u,d+1,g[u][i].second); siz[u]+=siz[v]; if(siz[son[u]]<siz[v]) son[u]=v; } } void dfs2(int u,int tp) { top[u]=tp; id[u]=++num; if(son[u]) dfs2(son[u],tp); for(int i=0;i<(int)g[u].size();i++) { int v=g[u][i].first; if(v==fa[u]||v==son[u]) continue; dfs2(v,v); } } int qL,qR; int p,v; int _max; int n; struct IntervalTree { int maxv[maxn*4]; void build(int o,int L,int R) { int M = L + (R-L)/2; if(L==R) maxv[o] = val[L]; else { build(o*2,L,M); build(o*2+1,M+1,R); maxv[o] = max(maxv[o*2],maxv[o*2+1]); } } void update(int o,int L,int R) { int M = L + (R-L)/2; if(L==R) maxv[o] = v; else { if(p<=M) update(o*2,L,M); else update(o*2+1,M+1,R); maxv[o] = max(maxv[o*2],maxv[o*2+1]); } } int qurey(int o,int L,int R) { int M = L + (R-L)/2, ans = -inf; if(qL<=L&&R<=qR) return maxv[o]; if(qL<=M) ans = max(ans,qurey(o*2,L,M)); if(M<qR) ans = max(ans,qurey(o*2+1,M+1,R)); return ans; } }sol; int yougth(int u,int v) { int f1 = top[u],f2 = top[v]; int ret = -inf; while(f1!=f2) { if(deep[f1]<deep[f2]) { swap(u,v); swap(f1,f2); } qL = id[f1],qR = id[u],_max = -inf; _max = max(_max,sol.qurey(1,1,n)); ret = max(ret,_max); u = fa[f1]; f1 = top[u]; } if(u==v) return ret; if(deep[u]>deep[v]) swap(u,v); qL = id[son[u]],qR=id[v],_max = -inf; _max = max(_max,sol.qurey(1,1,n)); ret = max(ret,_max); return ret; } int main(int argc, char const *argv[]) { // freopen("in.txt","r",stdin); int t; scanf("%d",&t); while(t--) { scanf("%d",&n); for (int i = 0; i < maxn; ++i) g[i].clear(); for (int i = 1; i < n; ++i) edges[i].read(); num = 0; dfs1(1,0,1,-inf); dfs2(1,1); for(int i=1; i <=n; i++) { p = id[i]; v = val[i]; sol.update(1,1,n); } char cmd[20]; while(scanf("%s",cmd),strcmp(cmd,"DONE")!=0) { if(strcmp(cmd,"QUERY")==0) { int u,v; scanf("%d%d",&u,&v); printf("%d\n",yougth(u,v)); } else { int a,b; scanf("%d%d",&a,&b); int t = fa[edges[a].y] == edges[a].x ? edges[a].y : edges[a].x; p = id[t],v = b; sol.update(1,1,n); } } } return 0; }
标签:integer space uil main bit const nlogn inf put
原文地址:http://www.cnblogs.com/TreeDream/p/7425130.html