spoj375 樹鏈剖分(單點更新,區間查詢)
http://www.spoj.com/problems/QTREE/
QTREE - Query on a tree
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
/**
spoj375 樹鏈剖分(單點更新,區間查詢)
參考:
http://blog.sina.com.cn/s/blog_7a1746820100wp67.html
總結的很經典,樹鏈剖分的第一題建議從它開始
*/
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
///#define debug
using namespace std;
const int maxn=10005;
int fa[maxn],siz[maxn],son[maxn],num[maxn],top[maxn],dep[maxn];
int tree[maxn*4],d[maxn][3];
int n,z;
int head[maxn],ip;
void init()
{
memset(head,-1,sizeof(head));
ip=0;
}
struct note
{
int v,w,next;
}edge[maxn*2];
void addedge(int u,int v,int w)
{
edge[ip].v=v,edge[ip].w=w,edge[ip].next=head[u],head[u]=ip++;
}
void dfs(int u,int pre)
{
son[u]=0,siz[u]=1;
dep[u]=dep[pre]+1;
fa[u]=pre;
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].v;
if(v==pre)continue;
dfs(v,u);
if(siz[v]>siz[son[u]])
son[u]=v;
siz[u]+=siz[v];
}
#ifdef debug
printf("%d:siz,son,dep,fa %d %d %d %d\n",u,siz[u],son[u],dep[u],fa[u]);
#endif
}
void build(int u,int tp)
{
num[u]=++z,top[u]=tp;
if(son[u]!=0)
{
build(son[u],top[u]);
}
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].v;
if(v==fa[u]||v==son[u])continue;
build(v,v);
}
#ifdef debug
printf("%d num,top %d %d\n",u,num[u],top[u]);
#endif // debug
}
void update(int root,int l,int r,int loc,int x)
{
if(l>loc||r<loc)return;
if(l==r)
{
tree[root]=x;
return;
}
int mid=(l+r)>>1;
update(root<<1,l,mid,loc,x);
update(root<<1|1,mid+1,r,loc,x);
tree[root]=max(tree[root<<1],tree[root<<1|1]);
#ifdef debug
printf("root,l,r,tree[root]%d %d %d %d\n",root,l,r,tree[root]);
#endif // debug
}
int maxi(int root,int l,int r,int a,int b)
{
if(r<a||l>b)return 0;
if(b>=r&&a<=l)
{
return tree[root];
}
int mid=(l+r)>>1;
return max(maxi(root<<1,l,mid,a,b),maxi(root<<1|1,mid+1,r,a,b));
}
int find(int va,int vb)
{
int f1=top[va],f2=top[vb],tmp=0;
while(f1!=f2)
{
if(dep[f1]<dep[f2])
{
swap(f1,f2);
swap(va,vb);
}
tmp=max(tmp,maxi(1,1,z,num[f1],num[va]));
va=fa[f1],f1=top[va];
}
if(va==vb)return tmp;
///兩點已經在同一條鏈上,但是不是同一個點
if(dep[va]>dep[vb])swap(va,vb);
return max(tmp,maxi(1,1,z,num[son[va]],num[vb]));
}
int main()
{
/// freopen("data.txt","r",stdin);
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
init();
memset(d,0,sizeof(d));
for(int i=1;i<n;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
d[i][0]=x,d[i][1]=y,d[i][2]=z;
addedge(x,y,z);
addedge(y,x,z);
}
int root=(n+1)>>1;
z=0,dep[0]=0;
dfs(root,0);
build(root,root);
for(int i=1;i<n;i++)
{
if(dep[d[i][0]]>dep[d[i][1]])
{
swap(d[i][0],d[i][1]);
}
update(1,1,z,num[d[i][1]],d[i][2]);
}
while(1)
{
char c[25];
scanf("%s",c);
if(c[0]=='D')break;
int a,b;
scanf("%d%d",&a,&b);
if(c[0]=='Q')
{
printf("%d\n",find(a,b));
}
else
{
update(1,1,z,num[d[a][1]],b);
}
}
}
return 0;
}
相關文章
- poj 3237 樹鏈剖分(區間更新,區間查詢)
- HYSBZ 2243 樹鏈剖分(區間更新,區間查詢)較難
- 樹狀陣列單點更新和區間查詢陣列
- HDU 1556【區間更新+單點查詢 樹狀陣列】陣列
- 樹鏈剖分
- 線段樹(1)建樹、單點修改、單點查詢、區間查詢和例題
- [OI] 樹鏈剖分
- 【樹狀陣列 區間更新區間查詢】code陣列
- 樹鏈剖分總結
- 淺談樹鏈剖分
- 變化的區間樹狀陣列,單點查詢陣列
- 【筆記/模板】樹鏈剖分筆記
- #8. 「模板」樹鏈剖分
- 樹鏈剖分學習筆記筆記
- 「學習筆記」樹鏈剖分筆記
- POJ 3468 【區間修改+區間查詢 樹狀陣列 | 線段樹 | 分塊】陣列
- 樹狀陣列模板題 & (樹狀陣列 1:單點修改,區間查詢)陣列
- codechef Dynamic GCD [樹鏈剖分 gcd]GC
- 2024.3.14 樹鏈剖分
- 對樹鏈剖分的愛 題解
- 1080 線段樹練習 單點修改及區間查詢
- BF的資料結構題單-提高組——樹鏈剖分資料結構
- 樹鏈剖分模板+入門題 SPOJ - QTREEQT
- P8025 【樹鏈剖分求祖先】
- 1081 線段樹練習 2 單點查詢及區間修改
- HDU 1556-Color the ball(樹狀陣列-區間修改 單點查詢)陣列
- 樹鏈剖分解析
- POJ 2155-Matrix(二維樹狀陣列-區間修改 單點查詢)陣列
- 一起來學習樹鏈剖分吧!
- POJ 1195-Mobile phones(二維樹狀陣列-區間更新區間查詢)陣列
- 樹狀陣列的區間查詢與區間修改陣列
- 芻議線段樹 2 (區間修改,區間查詢)
- 長鏈剖分模板
- HDU1166 敵兵佈陣【樹狀陣列 單點修改+區間查詢】陣列
- 長鏈剖分筆記筆記
- HDU1754 I Hate It 【線段樹基礎:點修改+區間查詢】
- bzoj4034: [HAOI2015]樹上操作(樹鏈剖分+線段樹)
- TZOJ 8472 : Tree (重鏈剖分+線段樹) POJ 3237