您的位置:首页 > 编程语言 > Qt开发

SPOJ QTREE 树链剖分

2015-08-27 17:32 453 查看
#include <cstdio>
#include <cstring>
#include <iostream>
#include <set>
#include <queue>
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std;
#define N 10010
#define ls o<<1
#define rs o<<1|1
#define define_m int m=(l+r)>>1
int maxn[N<<2] , dis
;

struct Edge{
int x,y,d;
Edge(int x=0 , int y=0 , int d=0):x(x),y(y),d(d){}
};

vector<Edge> v
;
int fa
, son
, sz
, top
, dep
, id
, k;
int n , st
, en
, d
, val;
char str[20];

void dfs(int u , int f , int d)
{
fa[u] = f;
sz[u] = 1 , dep[u]=d , son[u]=0;
int len = v[u].size();
int maxn = 0;
for(int i=0 ; i<len ; i++){
int to=v[u][i].y;
if(to==f) continue;
dfs(to,u,d+1);
sz[u]+=sz[to];
if(sz[to]>maxn){
son[u]=to;
maxn = sz[to];
}
}
}

void dfs1(int u , int f , int head)
{
int l=v[u].size();
top[u] = head;
if(son[u]){
id[son[u]] = ++k;
dfs1(son[u] , u , head);
}
for(int i=0 ; i<l ; i++){
int to = v[u][i].y;
if(to==f || to==son[u]) continue;
id[to] = ++k;
dfs1(to , u , to);
}
}

void push_up(int o)
{
maxn[o] = max(maxn[ls] , maxn[rs]);
}

void build(int o , int l , int r)
{
if(l==r){
maxn[o] = dis[l];
return ;
}
define_m;
build(ls , l , m);
build(rs , m+1 , r);
push_up(o);
}

void update(int o , int l , int r , int pos, int v)
{
if(l==r && l==pos){
maxn[o] = v;
return;
}
define_m;
if(m>=pos) update(ls , l , m , pos , v);
else update(rs , m+1 , r , pos , v);
push_up(o);
}

int query(int o , int l , int r , int s , int t)
{
//  cout<<"query: "<<o<<" "<<l<<" "<<r<<" "<<s<<" "<<t<<endl;
if(l>=s && r<=t){
return maxn[o];
}
int ans = 0;
define_m;
if(m>=s) ans = max(ans , query(ls , l , m , s , t));
if(m<t) ans= max(ans , query(rs , m+1 , r , s , t));
return ans;
}

int CalPath(int u , int v)
{
int top1=top[u] , top2=top[v];
int ans = 0;
while(top1 != top2){
if(dep[top1]<dep[top2]){
swap(top1 , top2);
swap(u , v);
}
ans = max(ans , query(1 , 1 , k , id[top1] , id[u]));
u=fa[top1];
top1=top[u];
}
if(u!=v){
if(dep[u]<dep[v]){
swap(u,v);
}
ans=max(ans,query(1,1,k,id[son[v]],id[u]));
// cout<<"in: "<<id[u]<<" "<<id[son[v]]<<endl;
// cout<<"u: "<<u<<" v: "<<v<<" "<<ans<<endl;
}
return ans;
}

int main()
{
// freopen("a.in" , "r" , stdin);
int T;
scanf("%d" , &T);
while(T--)
{
scanf("%d" , &n);
for(int i=1 ; i<=n ; i++) v[i].clear();
for(int i=1 ; i<n ; i++){
scanf("%d%d%d" , &st[i] , &en[i] , &d[i]);
v[st[i]].push_back(Edge(st[i],en[i],d[i]));
v[en[i]].push_back(Edge(en[i],st[i],d[i]));
}
k=0;
dfs(1,0,1);
dfs1(1,0,1);
for(int i=1 ; i<n ; i++){
int ID;
if(st[i] != fa[en[i]]) ID = id[st[i]];
else ID = id[en[i]];
//  cout<<"ID: "<<ID<<endl;
dis[ID] = d[i];
}
/* for(int i=1 ; i<=n ; i++){
cout<<fa[i]<<" "<<son[i]<<" "<<dep[i]<<" "<<sz[i]<<" "<<top[i]<<" "<<id[i]<<endl;
if(i<n) cout<<"i: "<<dis[i]<<endl;
}*/
build(1,1,k);
// cout<<"sum: "<<sum[1]<<" "<<sum[2]<<" "<<sum[3]<<endl;
while(scanf("%s" , str) && str[0]!='D'){
int t1 , t2;
scanf("%d%d" , &t1 , &t2);
if(str[0] == 'C'){
int ID;
if(st[t1] != fa[en[t1]]) ID = id[st[t1]];
else ID = id[en[t1]];
//  cout<<"ID: "<<ID<<endl;
update(1,1,k,ID,t2);
}
else{
int ans = CalPath(t1,t2);
printf("%d\n" , ans);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: