您的位置:首页 > 产品设计 > UI/UE

SPOJ375 Query on a tree(树链剖分)

2017-12-26 21:38 459 查看

 

传送门

 

题意

给出一棵树,每条边都有权值,有两种操作:

  • 把第p条边的权值改为x
  • 询问x,y路径上的权值最大的边

code

#include<cstdio>
#include<algorithm>
#include<cstring>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

using namespace std;

const int N = 100010;
struct Edge {
int to,nxt,w;
}e[200100];
int head
,tot,tn,n;
int deth
,son
,fa
,siz
,bel
,pos
;
int mx[N<<2],a
,b
,c
,data
;

void init() {
tot = tn = 0;
memset(head,0,sizeof(head));
memset(son,0,sizeof(son));
}
inline void add_edge(int u,int v,int w) {
e[++tot].to = v,e[tot].w = w,e[tot].nxt = head[u],head[u] = tot;
}
void dfs1(int u,int pa) {
siz[u] = 1;
for (int i=head[u]; i; i=e[i].nxt) {
int v = e[i].to;
if (v==pa) continue;
fa[v] = u;
deth[v] = deth[u] + 1;
dfs1(v,u);
siz[u] += siz[v];
if (son[u]==0 || siz[v] > siz[son[u]]) son[u] = v;
}
}
void dfs2(int u,int top) {
pos[u] = ++tn;
bel[u] = top;
if (!son[u]) return ;
dfs2(son[u],top);
for (int i=head[u]; i; i=e[i].nxt) {
int v = e[i].to;
if (v != fa[u] && v != son[u]) dfs2(v,v);
}
}
void pushup(int rt) {
mx[rt] = max(mx[rt<<1],mx[rt<<1|1]);
}
void build(int l,int r,int rt) {
if (l==r) {
mx[rt] = data[l];return ;
}
int m = (l + r) >> 1;
build(lson);
build(rson);
pushup(rt);
}
void update(int l,int r,int rt,int p,int x) {
if (l==r) {
mx[rt] = x;return ;
}
int m = (l + r) >> 1;
if (p <= m) update(lson,p,x);
else update(rson,p,x);
pushup(rt);
}
int query(int l,int r,int rt,int L,int R) {
if (L <= l && r <= R) {
return mx[rt];
}
int m = (l + r) >> 1;
int ret = -1e9;
if (L <= m) ret = max(ret,query(lson,L,R));
if (R > m)  ret = max(ret,query(rson,L,R));
return ret;
}
void Change(int p,int x) {
if (deth[a

] > deth[b[p]]) update(2,n,1,pos[a[p]],x); else update(2,n,1,pos[b[p]],x); } int Ask(int x,int y) { int ans = -1e9; while (bel[x] != bel[y]) { if (deth[bel[x]] < deth[bel[y]]) swap(x,y); ans = max(ans,query(2,n,1,pos[bel[x]],pos[x])); x = fa[bel[x]]; } if (deth[x] > deth[y]) swap(x,y); if (x != y) ans = max(ans,query(2,n,1,pos[x]+1,pos[y])); return ans; } int main() { char opt[15]; int T;scanf("%d",&T); while (T--) { init(); scanf("%d",&n); for (int i=1; i<n; ++i) { scanf("%d%d%d",&a[i],&b[i],&c[i]); add_edge(a[i],b[i],c[i]); add_edge(b[i],a[i],c[i]); } deth[1] = 1; dfs1(1,0); dfs2(1,1); for (int i=1; i<n; ++i) { if (deth[a[i]] > deth[b[i]]) data[pos[a[i]]] = c[i]; // 一定是pos else data[pos[b[i]]] = c[i]; } build(2,n,1); scanf("%s",opt); while (opt[0]!='D') { int x,y; scanf("%d%d",&x,&y); if (opt[0]=='Q') printf("%d\n",Ask(x,y)); else Change(x,y); scanf("%s",opt); } } return 0; }

[p] 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: