【BZOJ 3307】 3307: 雨天的尾巴 (线段树+树链剖分)
3307: 雨天的尾巴
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 458 Solved: 210Description
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个点存放最多的物品是哪一种,如果有
多种物品的数量一样,输出编号最小的。如果某个点没有物品
则输出0Sample Input
20 50
8 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
87
36
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
HINT
Source
【分析】
什么时候样例这样良心。。
按照z排序,然后树剖标记一下区间,然后统计个数相同的区间add到线段树里面求min,这些区间个数不会超过3*mlogn,因为树剖区间logn个,一个新的区间最多只会把原来的分割成3部分。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 using namespace std; 7 #define Maxn 100010 8 9 int mymax(int x,int y) {return x>y?x:y;} 10 11 struct node 12 { 13 int l,r,lc,rc,mx,id; 14 int lazy,lad; 15 }tr[Maxn*2]; 16 17 struct nnode{int x,y,z;}t[Maxn],tt[Maxn],t3[Maxn*40]; 18 int first[Maxn],len; 19 20 bool cmp(nnode x,nnode y) {return x.z<y.z;} 21 bool cmp2(nnode x,nnode y) {return x.x<y.x;} 22 23 void ins(int x,int y) 24 { 25 t[++len].x=x;t[len].y=y; 26 t[len].z=first[x];first[x]=len; 27 } 28 29 int fa[Maxn],son[Maxn],tp[Maxn],sm[Maxn],dep[Maxn]; 30 void dfs1(int x,int ff) 31 { 32 dep[x]=dep[ff]+1; 33 fa[x]=ff;sm[x]=1;son[x]=0; 34 for(int i=first[x];i;i=t[i].z) if(t[i].y!=ff) 35 { 36 int y=t[i].y; 37 dfs1(y,x); 38 sm[x]+=sm[y]; 39 if(son[x]==0||sm[y]>sm[son[x]]) son[x]=y; 40 } 41 } 42 43 int cnt,dfn[Maxn]; 44 void dfs2(int x,int tpp) 45 { 46 dfn[x]=++cnt;tp[x]=tpp; 47 if(son[x]) dfs2(son[x],tpp); 48 for(int i=first[x];i;i=t[i].z) if(t[i].y!=fa[x]&&t[i].y!=son[x]) 49 { 50 int y=t[i].y; 51 dfs2(y,y); 52 } 53 } 54 55 int tot=0; 56 int build(int l,int r) 57 { 58 int x=++tot; 59 tr[x].l=l;tr[x].r=r;tr[x].mx=0;tr[x].lazy=0; 60 if(l!=r) 61 { 62 int mid=(l+r)>>1; 63 tr[x].lc=build(l,mid); 64 tr[x].rc=build(mid+1,r); 65 } 66 else tr[x].lc=tr[x].rc=0; 67 return x; 68 } 69 70 void upd(int x) 71 { 72 if(tr[x].lazy==0) return; 73 int lc=tr[x].lc,rc=tr[x].rc; 74 if(tr[x].lazy>tr[x].mx) tr[x].mx=tr[x].lazy,tr[x].id=tr[x].lad; 75 if(tr[x].l==tr[x].r) {tr[x].lazy=0;return;} 76 if(tr[x].lazy>tr[lc].lazy) tr[lc].lazy=tr[x].lazy,tr[lc].lad=tr[x].lad; 77 if(tr[x].lazy>tr[rc].lazy) tr[rc].lazy=tr[x].lazy,tr[rc].lad=tr[x].lad; 78 tr[x].lazy=0; 79 } 80 81 void change(int x,int l,int r,int y,int id) 82 { 83 if(tr[x].l==l&&tr[x].r==r) 84 { 85 if(y>tr[x].lazy) tr[x].lazy=y,tr[x].lad=id; 86 upd(x);return; 87 } 88 upd(x); 89 int mid=(tr[x].l+tr[x].r)>>1; 90 if(r<=mid) change(tr[x].lc,l,r,y,id); 91 else if(l>mid) change(tr[x].rc,l,r,y,id); 92 else {change(tr[x].lc,l,mid,y,id);change(tr[x].rc,mid+1,r,y,id);} 93 if(tr[tr[x].lc].mx>=tr[tr[x].rc].mx) tr[x].mx=tr[tr[x].lc].mx,tr[x].id=tr[tr[x].lc].id; 94 else tr[x].mx=tr[tr[x].rc].mx,tr[x].id=tr[tr[x].rc].id; 95 } 96 97 int query(int x,int y) 98 { 99 upd(x); 100 if(tr[x].l==tr[x].r) return tr[x].id; 101 int mid=(tr[x].l+tr[x].r)>>1; 102 if(y<=mid) return query(tr[x].lc,y); 103 return query(tr[x].rc,y); 104 } 105 106 int tl; 107 int add(int x,int y) 108 { 109 while(tp[x]!=tp[y]) 110 { 111 if(dep[tp[x]]<dep[tp[y]]) swap(x,y); 112 t3[++tl].x=dfn[tp[x]];t3[tl].y=1; 113 t3[++tl].x=dfn[x]+1;t3[tl].y=-1; 114 x=fa[tp[x]]; 115 } 116 if(dep[x]>dep[y]) swap(x,y); 117 t3[++tl].x=dfn[x];t3[tl].y=1; 118 t3[++tl].x=dfn[y]+1;t3[tl].y=-1; 119 } 120 121 void ffind(int st,int ed,int id) 122 { 123 tl=0; 124 for(int i=st;i<=ed;i++) 125 { 126 add(tt[i].x,tt[i].y); 127 } 128 sort(t3+1,t3+1+tl,cmp2); 129 int nw=0; 130 for(int i=1;i<tl;i++) 131 { 132 nw+=t3[i].y; 133 if(t3[i].x!=t3[i+1].x&&nw!=0) 134 { 135 // printf("%d %d %d\n",t3[i].x,t3[i+1].x-1,nw); 136 change(1,t3[i].x,t3[i+1].x-1,nw,id); 137 } 138 } 139 } 140 141 int main() 142 { 143 int n,m; 144 scanf("%d%d",&n,&m); 145 len=0; 146 memset(first,0,sizeof(first)); 147 for(int i=1;i<n;i++) 148 { 149 int x,y; 150 scanf("%d%d",&x,&y); 151 ins(x,y);ins(y,x); 152 } 153 dep[0]=0;dfs1(1,0); 154 cnt=0;dfs2(1,1); 155 for(int i=1;i<=m;i++) scanf("%d%d%d",&tt[i].x,&tt[i].y,&tt[i].z); 156 sort(tt+1,tt+1+m,cmp); 157 build(1,n); 158 int st=1; 159 for(int i=1;i<=m;i++) 160 { 161 if(i==m||tt[i].z!=tt[i+1].z) 162 { 163 ffind(st,i,tt[i].z); 164 st=i+1; 165 } 166 } 167 for(int i=1;i<=n;i++) printf("%d\n",query(1,dfn[i])); 168 return 0; 169 }
2017-03-27 16:10:51