[bzoj3307] 雨天的尾巴
阿新 • • 發佈:2019-01-11
urn upd read str dig con using put map
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
Solution
樹上差分+線段樹合並,隨便搞搞就好了。
註意權值要離散化。
#include<bits/stdc++.h> using namespace std; void read(int &x) { x=0;int f=1;char ch=getchar(); for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f; for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f; } void print(int x) { if(x<0) putchar('-'),x=-x; if(!x) return ;print(x/10),putchar(x%10+48); } void write(int x) {if(!x) putchar('0');else print(x);putchar('\n');} const int maxn = 1e5+10; const int N = 1e5; int n,m,mp_cnt,rt[maxn],ls[maxn*50],rs[maxn*50],sum[maxn*50],seg,ans[maxn]; map<int,int > mp; #define mid ((l+r)>>1) struct Segment_Tree { void update(int p) {sum[p]=max(sum[ls[p]],sum[rs[p]]);} void modify(int &p,int l,int r,int x,int z) { if(!p) p=++seg; if(l==r) return sum[p]+=z,void(); if(x<=mid) modify(ls[p],l,mid,x,z); else modify(rs[p],mid+1,r,x,z); update(p); } int query(int &p,int l,int r) { if(!sum[p]) return 0; if(l==r) return l; if(sum[ls[p]]==sum[p]) return query(ls[p],l,mid); else return query(rs[p],mid+1,r); } int merge(int x,int y) { if(!x||!y) return x+y; if((!ls[x])&&(!rs[x])&&(!ls[y])&&(!rs[y])) return sum[x]+=sum[y],x; ls[x]=merge(ls[x],ls[y]); rs[x]=merge(rs[x],rs[y]); update(x); return x; } }SGT; struct Input_Tree { int head[maxn],tot,f[maxn][20],dep[maxn]; struct edge{int to,nxt;}e[maxn<<1]; void add(int u,int v) {e[++tot]=(edge){v,head[u]},head[u]=tot;} void ins(int u,int v) {add(u,v),add(v,u);} void dfs(int x,int fa) { f[x][0]=fa,dep[x]=dep[fa]+1; for(int i=1;i<=19;i++) f[x][i]=f[f[x][i-1]][i-1]; for(int i=head[x];i;i=e[i].nxt) if(e[i].to!=fa) dfs(e[i].to,x); } int lca(int x,int y) { if(dep[x]<dep[y]) swap(x,y); for(int i=19;~i;i--) if(dep[f[x][i]]>=dep[y]) x=f[x][i]; if(x==y) return x; for(int i=19;~i;i--) if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i]; return f[x][0]; } void solve(int x,int fa) { for(int i=head[x];i;i=e[i].nxt) if(e[i].to!=fa) { solve(e[i].to,x); rt[x]=SGT.merge(rt[x],rt[e[i].to]); } ans[x]=SGT.query(rt[x],1,m); if(!sum[rt[x]]) ans[x]=0; } }T; int inx[maxn],iny[maxn],inz[maxn],r[maxn]; int main() { read(n),read(m); for(int i=1,x,y;i<n;i++) read(x),read(y),T.ins(x,y); T.dfs(1,0); for(int i=1;i<=m;i++) read(inx[i]),read(iny[i]),read(inz[i]),r[i]=inz[i]; sort(r+1,r+m+1); int M=unique(r+1,r+m+1)-r-1; for(int i=1;i<=m;i++) inz[i]=lower_bound(r+1,r+M+1,inz[i])-r; for(int i=1;i<=m;i++) { int x=inx[i],y=iny[i],z=inz[i]; int t=T.lca(x,y); SGT.modify(rt[x],1,m,z,1); SGT.modify(rt[y],1,m,z,1); SGT.modify(rt[t],1,m,z,-1); if(T.f[t][0]) SGT.modify(rt[T.f[t][0]],1,m,z,-1); } T.solve(1,0); for(int i=1;i<=n;i++) printf("%d\n",r[ans[i]]); return 0; }
[bzoj3307] 雨天的尾巴