您的位置:首页 > 其它

hdu5029 树链剖分 + 线段树

2015-08-01 23:35 302 查看
将树映射在线段上进行操作 然后每个 重链变成一个连续的区间

#include <iostream>
#include <cstdio>
#include <string.h>
#include <vector>
#include <algorithm>
#pragma comment(linker,"/STACk:10240000,10240000")
using namespace std;
const int maxn=100005;
vector<int>F[maxn];
int son[maxn],num[maxn],fa[maxn],top[maxn],p[maxn],fp[maxn],pos,depth[maxn],ans[maxn];
vector<int>P[maxn];
int loc,v;
struct SegmentItree{
int num[maxn*4],id[maxn*4];
void build(int o,int L, int R){
num[o]=0;
id[o]=0;
if(L>=R){
num[o]=0; id[o]=L;
return ;
}
int mid = (L+R)/2;
build(o*2,L,mid );
build(o*2+1,mid+1,R);
}
void maintain(int o){
num[o]=0;
id[o]=0;
if(num[o*2]==0&&num[o*2+1]==0)return;
if( num[o*2] >= num[o*2+1] ){
num[o]=num[o*2];
id[o]=id[o*2];
} else{
num[o] =num[o*2+1];
id[o]=id[o*2+1];
}
}
void add(int o,int L, int R){
if(L>=R){
num[o]+=v;
return ;
}
int mid = (L+R)>>1;
if(loc<=mid){
add(o*2,L,mid);
}else{
add(o*2+1, mid+1,R);
}
maintain(o);
}
}T;
void inti(int n){
for(int i=0; i<=n+2; ++i)
F[i].clear(),P[i].clear();
pos=0;
}
void dfs(int cur, int per,int dep){
depth[cur]=dep;
son[cur]=-1;
fa[cur]=per;
num[cur]=1;
int Len= F[cur].size();
for(int i=0; i<Len; ++i){
int to = F[cur][i];
if(to==per) continue;
dfs(to,cur,dep+1);
num[cur]+=num[to];
if( son[ cur ] == -1 || num[ son[cur] ]< num[to] ) son[cur]=to;
}
}
void finde(int cur , int per, int xx){
top[cur]=xx;
pos++;
p[cur]=pos;
fp[pos]=cur;
if(son[cur]!=-1)
finde(son[cur],cur,xx);
int len = F[cur].size();
for(int i=0; i<len ;++i ){
int to= F[cur][i];
if(to==per||to==son[cur])continue;
finde(to,cur,to);
}
}
void solve(int x, int y,int d){
int f1=top[x],f2=top[y];
while(f1!=f2){
if(depth[f1]<depth[f2]){
int temp = x; x=y; y= temp;
temp=f1; f1=f2; f2=temp;
}
P[ p[f1] ].push_back(d);
P[ p[x]+1 ].push_back(-d);
x=fa[f1];
f1=top[x];
}
if(depth[x]>depth[y]){
int temp = x; x = y ; y= temp;
}
P[p[x]].push_back(d);
P[p[y]+1].push_back(-d);
}
int main()
{
int n,m;
for(;;){
scanf("%d%d",&n,&m);
if(n==0&&m==0)break;
inti(n);
for(int i=1; i<n ;++i ){
int a,b;
scanf("%d%d",&a,&b);
F[a].push_back(b);
F[b].push_back(a);
}
dfs(1,0,0);
finde(1,0,1);
int N=0;
for(int i=0; i<m; ++i){
int a,b,d;
scanf("%d%d%d",&a,&b,&d);
solve(a,b,d);
N=max(d,N);
}
memset(ans,0,sizeof(ans));
if(N!=0){
T.build(1,1,N);
for(int i=1; i<=n; ++i){
int L = P[i].size();
for(int j=0; j<L; ++j){
int to= P[i][j];
if(to>0){
v=1;
loc=to;
}else{
v=-1;
loc=-to;
}
T.add(1,1,N);
}
if(T.num[1]!=0)
ans[fp[i]]=T.id[1];
else ans[fp[i]]=0;
}
}
for(int i=1; i<=n; ++i)
printf("%d\n",ans[i]);
}
return 0;
}


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