BZOJ 3307: 雨天的尾巴 线段树合并 树上差分
2017-08-28 15:26
501 查看
3307: 雨天的尾巴
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 610 Solved: 254
[Submit][Status][Discuss]
Description
N个点,形成一个树状结构。有M次发放,每次选择两个点x,y对于x到y的路径上(含x,y)每个点发一袋Z类型的物品。完成
所有发放后,每个点存放最多的是哪种物品。
Input
第一行数字N,M接下来N-1行,每行两个数字a,b,表示a与b间有一条边
再接下来M行,每行三个数字x,y,z.如题
Output
输出有N行每i行的数字表示第i个点存放最多的物品是哪一种,如果有
多种物品的数量一样,输出编号最小的。如果某个点没有物品
则输出0
Sample Input
20 508 6
10 6
18 6
20 10
7 20
2 18
19 8
1 6
14 20
16 10
13 19
3 14
17 18
11 19
4 11
15 14
5 18
9 10
12 15
11 14 87
12 1 87
14 3 84
17 2 36
6 5 93
17 6 87
10 14 93
5 16 78
6 15 93
15 5 16
11 8 50
17 19 50
5 4 87
15 20 78
1 17 50
20 13 87
7 15 22
16 11 94
19 8 87
18 3 93
13 13 87
2 1 87
2 6 22
5 20 84
10 12 93
18 12 87
16 10 93
8 17 93
14 7 36
7 4 22
5 9 87
13 10 16
20 11 50
9 16 84
10 17 16
19 6 87
12 2 36
20 9 94
9 2 84
14 1 94
5 5 94
8 17 16
12 8 36
20 17 78
12 18 50
16 8 94
2 19 36
10 18 36
14 19 50
4 12 50
Sample Output
8736
84
22
87
87
22
50
84
87
50
36
87
93
36
94
16
87
50
50
1<=N,M<=100000
1<=a,b,x,y<=N
1<=z<=10^9
对每个节点建权值线段树,树上差分再合并就行了
树上差分就不多说了
这两天发现线段树合并真是个好东西
每个节点的答案递归可以由子树合并而来
听说好像可以链剖? 不会 嘿嘿
#include<cmath>
#include<ctime>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<string>
#include<bitset>
#include<queue>
#include<map>
#include<set>
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
void print(int x)
{if(x<0)putchar('-'),x=-x;if(x>=10)print(x/10);putchar(x%10+'0');}
const int N=100100;
int n,m,maxn;
int ecnt,last
;
struct EDGE{int to,nt;}e[N<<1];
inline void add(int u,int v)
{e[++ecnt]=(EDGE){v,last[u]};last[u]=ecnt;}
struct changeopt{int u,v,val;friend bool operator <(const changeopt &x,const changeopt &y){return x.val<y.val;}}o
;
int fa
[18],d
,dfn
,pos
,ref
,root
,ans
,cnt;
void dfs(int u)
{
dfn[u]=++cnt;pos[cnt]=u;
for(int i=1;(1<<i)<=d[u];++i)fa[u][i]=fa[fa[u][i-1]][i-1];
for(int i=last[u];i;i=e[i].nt)
{
if(fa[u][0]==e[i].to)continue;
fa[e[i].to][0]=u;d[e[i].to]=d[u]+1;dfs(e[i].to);
}
}
inline int getlca(int u,int v)
{
if(d[u]<d[v])swap(u,v);
int len=d[u]-d[v];
for(int i=0;(1<<i)<=len;++i)if(len&(1<<i))u=fa[u][i];
if(u==v)return u;
for(int i=17;i>=0;--i)if(fa[u][i]^fa[v][i])
u=fa[u][i],v=fa[v][i];
return fa[u][0];
}
struct val_tree{int w,mx,ls,rs;}tr[N<<6];
inline void pushup(int k)
{tr[k].mx=max(tr[tr[k].ls].mx,tr[tr[k].rs].mx);}
inline void modify(int &k,int x,int l,int r,int val,int p)
{
k=++cnt;tr[k].w=tr[x].w+p;
if(l==r){tr[k].mx=tr[k].w;return ;}
int mid=(l+r)>>1;
tr[k].ls=tr[x].ls;tr[k].rs=tr[x].rs;
val<=mid?modify(tr[k].ls,tr[x].ls,l,mid,val,p):modify(tr[k].rs,tr[x].rs,mid+1,r,val,p);
pushup(k);
}
int merge(int x,int y,int l,int r)
{
if(!x)return y;if(!y)return x;
int mid=(l+r)>>1;
tr[x].w=tr[x].w+tr[y].w;
if(l==r){tr[x].mx=tr[x].w;return x;}
tr[x].ls=merge(tr[x].ls,tr[y].ls,l,mid);
tr[x].rs=merge(tr[x].rs,tr[y].rs,mid+1,r);
pushup(x);
return x;
}
int query(int k,int l,int r)
{
if(!tr[k].w)return 0;
if(l==r)return l;
int mid=(l+r)>>1;
if(tr[tr[k].ls].mx==tr[k].mx)return query(tr[k].ls,l,mid);
return query(tr[k].rs,mid+1,r);
}
int main()
{
n=read();m=read();
register int i,u,v,val=0,lca,falca;
for(i=1;i<n;++i){u=read();v=read();add(u,v);add(v,u);}
for(i=1;i<=m;++i){o[i].u=read();o[i].v=read();o[i].val=read();}
dfs(1);
sort(o+1,o+1+m);
maxn=1;ref[1]=o[1].val;
for(i=2;i<=m;++i){if(o[i].val^ref[maxn])maxn++;ref[maxn]=o[i].val;}
for(i=1;i<=m;++i)
{
u=o[i].u;v=o[i].v;if(o[i].val^o[i-1].val)val++;
lca=getlca(u,v);falca=fa[lca][0];
modify(root[u],root[u],1,maxn,val,1);
modify(root[v],root[v],1,maxn,val,1);
modify(root[lca],root[lca],1,maxn,val,-1);
if(falca)modify(root[falca],root[falca],1,maxn,val,-1);
}
for(i=n;i;i--)
{
root[fa[pos[i]][0]]=merge(root[fa[pos[i]][0]],root[pos[i]],1,maxn);
ans[pos[i]]=query(root[pos[i]],1,maxn);
}
for(i=1;i<=n;++i)print(ref[ans[i]]),puts("");
return 0;
}
相关文章推荐
- BZOJ_3307_雨天的尾巴_线段树合并+树上差分
- [BZOJ]3307: 雨天的尾巴 线段树合并+树上差分
- 【BZOJ3307】雨天的尾巴-线段树合并+树上差分
- bzoj 3307: 雨天的尾巴【树剖lca+树上差分+线段树合并】
- BZOJ 3307: 雨天的尾巴( LCA + 线段树合并 )
- 【bzoj3307】雨天的尾巴 权值线段树合并
- 【BZOJ3307】雨天的尾巴 线段树合并
- [BZOJ3307][线段树合并]雨天的尾巴
- [bzoj3307]雨天的尾巴_线段树合并
- BZOJ3307 雨天的尾巴 (树链剖分 线段树合并 dfs相关)
- bzoj 3307: 雨天的尾巴 (线段树合并+LCA)
- [bzoj3307]雨天的尾巴【线段树】
- 【BZOJ3307】雨天的尾巴(树链剖分+树上差分+线段树)
- bzoj 3307: 雨天的尾巴 线段树
- BZOJ 3307 雨天的尾巴 线段树
- BZOJ 3307 雨天的尾巴 树上差分+lca+权值线段树合并
- [BZOJ3307][雨天的尾巴][树链剖分+线段树]
- BZOJ 3307: 雨天的尾巴
- bzoj3307 雨天的尾巴
- 【BZOJ3307】雨天的尾巴(权限题)