国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

spojQTREE - Query on a tree樹鏈剖分

2019-11-08 18:46:36
字體:
來源:轉載
供稿:網友

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: CHANGE i ti : change the cost of the i-th edge to ti or QUERY a b : ask for the maximum edge cost on the path from node a to node b Input The first line of input contains an integer t, the number of test cases (t <= 20). t test cases follow. For each test case: In the first line there is an integer N (N <= 10000), In the next N-1 lines, the i-th line describes the i-th edge: a line with three integers a b c denotes an edge between a, b of cost c (c <= 1000000), The next lines contain instructions “CHANGE i ti” or “QUERY a b”, The end of each test case is signified by the string “DONE”. There is one blank line between successive tests. Output For each “QUERY” Operation, write one integer rePResenting its result. Example Input: 1

3 1 2 1 2 3 2 QUERY 1 2 CHANGE 1 3 QUERY 1 2 DONE

Output: 1 3

第一道樹剖 講解蠻好的:http://m.blog.csdn.net/article/details?id=52330316

#include <cstdio>#include <iostream>#include <cstring>#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1using namespace std;const int maxn = 20010;char s[20];int fa[maxn],dep[maxn],siz[maxn],son[maxn];int n,a,b,c,tot,head[maxn],cnt,in[maxn];int top[maxn],w[maxn],totw,tmp[maxn],getin[maxn];struct node{ int u,v,w,num; int next;}edges[maxn*4];struct stus{ int maxal;}tree[maxn*8];void add(int u,int v,int w,int i){ edges[tot].num = i;edges[tot].v=v;edges[tot].w = w;edges[tot].next = head[u];head[u] = tot++; edges[tot].num = i;edges[tot].v = u;edges[tot].w = w;edges[tot].next = head[v];head[v] = tot++;}void init(){ scanf("%d",&n); tot = 0; memset(head,-1,sizeof(head)); for(int i = 1 ; i < n ;i++){ scanf("%d%d%d",&a,&b,&c); add(a,b,c,i); } for(int i = 1; i <= n ; i++) top[i] = i;}//fa、dep、siz、son//siz[v]表示以v為根的子樹的節點數//dep[v]表示v的深度(根深度為1)//fa[v]表示v的父親,//son[v]表示與v在同一重鏈上的v的兒子節點(姑且稱為重兒子)void dfs1(int now,int root,int h){ siz[now] = 1; dep[now] = h; fa[now] = root; int ans = -1; for(int k = head[now] ; k != -1 ;k = edges[k].next){ if(edges[k].v == root) continue; dfs1(edges[k].v,now,h+1); siz[now] += siz[edges[k].v]; if(siz[edges[k].v] > ans){ ans = siz[edges[k].v]; son[now] = edges[k].v; } }}//top[v]表示v所在的重鏈的頂端節點//w[v]表示v與其父親節點的連邊在線段樹中的位置void dfs2(int now,int root){ top[son[now]] = top[now]; if(son[now] != -1){ w[son[now]] = ++totw; dfs2(son[now],now); } else return; for(int k = head[now] ; k!= -1; k = edges[k].next){ if(edges[k].v == root) continue; if(son[now] == edges[k].v){ tmp[w[edges[k].v]] = edges[k].w; in[edges[k].num] = w[edges[k].v]; continue; } w[edges[k].v] = ++totw; tmp[totw] = edges[k].w; in[edges[k].num] = totw; dfs2(edges[k].v,now); }}void build(int l,int r,int rt){ if(l == r){ tree[rt].maxal = tmp[++cnt]; //in[getin[cnt]] = rt; // printf("tree[%d] = %d",rt,tree[rt].maxal); return; } int m = (l+r)>>1; build(lson); build(rson); tree[rt].maxal = max(tree[rt<<1].maxal,tree[rt<<1|1].maxal); //printf("tree[%d] = %d/n",rt,tree[rt].maxal);}int qurry(int l,int r,int rt,int ql,int qr){ if(ql <= l && qr >= r){ // printf("tree[%d] = %d/n",rt,tree[rt].maxal); return tree[rt].maxal; } int m = (l+r) >>1,ansnow = 0; //printf("ql = %d m = %d/n",ql,m); if(ql <= m) ansnow = max(ansnow,qurry(lson,ql,qr)); // printf("ansnow = %d/n",ansnow); if(qr > m) ansnow = max(ansnow,qurry(rson,ql,qr)); // printf("ansnow = %d/n",ansnow); return ansnow;}void sov(){ memset(son,-1,sizeof(son)); dfs1(1,-1,1); fa[1] = 1; totw = 0; top[1] = 1; dfs2(1,-1); w[1] = 0;// for(int i = 1;i <= n ; i++){// printf("node = %d top = %d son = %d w = %d dep = %d fa = %d/n",i,top[i],son[i],w[i],dep[i],fa[i]);// }// for(int i = 1; i <= totw; i++)// printf("getin[%d] = %d/n",i,getin[i]); cnt = 0; build(1,totw,1);// for(int i = 1; i <= n-1; i++)// printf("in[%d] = %d/n",i,in[i]);}void update(int l,int r,int rt,int pos,int b){ if(l == r ){ if(l == pos){ tree[rt].maxal = b; //printf("di tree[%d] = %d/n",pos,tree[pos].maxal); } // printf("rt tree[%d] = %d/n",l,rt); return; } int m = (l+r)>>1; if(m >= pos) update(lson,pos,b); if(m < pos) update(rson,pos,b); tree[rt].maxal = max(tree[rt<<1].maxal,tree[rt<<1|1].maxal); //printf("tree[%d] = %d/n",rt,tree[rt].maxal);}int cfind(int u,int v){ int tp1 = top[u],tp2 = top[v] ; // printf("tp1 = top[%d] = %d tp2 = top[%d] == %d/n",u,top[u],v,top[v]); int ans = 0; while(tp1 != tp2){ if(dep[tp1] < dep[tp2]){ swap(tp1,tp2); swap(u,v); } ans = max(ans,qurry(1,totw,1,w[tp1],w[u])); u = fa[tp1]; tp1 = top[u]; } if(u == v) return ans; if(dep[u] > dep[v]) swap(u,v); // printf("w[%d]+1 = %d w[%d] = %d/n",u,w[u]+1,v,w[v]); ans = max(ans,qurry(1,totw,1,w[u]+1,w[v])); return ans;}void cinqurry(){ while(1){ scanf("%s",s); if(s[0] == 'D') break; scanf("%d%d",&a,&b); if (s[0] == 'Q'){ printf("%d/n",cfind(a,b)); } else{ //單點修改 update(1,totw,1,in[a],b); } }}int main(){ int t; scanf("%d",&t); for(int ca = 1; ca <= t ;ca++){ init(); sov(); cinqurry(); } return 0;}/*1141 4 104 8 604 9 204 10 509 13 3013 14 401 2 902 5 1302 6 1006 12 1206 11 1101 3 703 7 80QUERY 1 2CHANGE 7 300QUERY 1 2DONE*/
上一篇:1012. The Best Rank (25)

下一篇:Hibernate中

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 三门峡市| 呼图壁县| 苍南县| 时尚| 安西县| 体育| 金坛市| 伊宁县| 高雄县| 夏邑县| 凤冈县| 南华县| 怀来县| 吴川市| 桐柏县| 瓦房店市| 杭锦旗| 台中市| 册亨县| 桐庐县| 滦平县| 兰溪市| 银川市| 漠河县| 湄潭县| 塔城市| 巴楚县| 且末县| 杭锦后旗| 龙川县| 福泉市| 漳浦县| 化州市| 右玉县| 玉树县| 南召县| 融水| 吴堡县| 潞城市| 郁南县| 康乐县|