bzoj 3307 雨天的尾巴
Posted Kurokey
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 3307 雨天的尾巴相关的知识,希望对你有一定的参考价值。
题目链接:传送门
题目大意:中文题,略
题目思路:网上有题解说是合并线段树的,但是太难蒟蒻不会,只能用树剖求解
如果不是树而是一维数组我们会怎么解?
当然是利用前缀和思想标记 (L) v+1,(R+1) v-1,然后扫一遍
用线段树取最大复杂度 nlogn
现在是搬到了树上,怎么做?
利用树链剖分拆成链然后在像一维那样做就行,复杂度n(logn)^2
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cmath> 5 #include <algorithm> 6 #include <cstring> 7 #include <stack> 8 #include <cctype> 9 #include <queue> 10 #include <string> 11 #include <vector> 12 #include <set> 13 #include <map> 14 #include <climits> 15 #define lson rt<<1,l,mid 16 #define rson rt<<1|1,mid+1,r 17 #define fi first 18 #define se second 19 #define ping(x,y) ((x-y)*(x-y)) 20 #define mst(x,y) memset(x,y,sizeof(x)) 21 #define mcp(x,y) memcpy(x,y,sizeof(y)) 22 using namespace std; 23 #define gamma 0.5772156649015328606065120 24 #define MOD 1000000007 25 #define inf 0x3f3f3f3f 26 #define N 100005 27 #define maxn 30010 28 typedef pair<int,int> PII; 29 typedef long long LL; 30 LL read(){ 31 LL x=0,f=1;char ch=getchar(); 32 while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} 33 while(ch>=‘0‘&&ch<=‘9‘){x=(x<<3)+(x<<1)+ch-‘0‘;ch=getchar();} 34 return x*f; 35 } 36 vector<int>V[N]; 37 map<int,int>M; 38 int num[N],ncnt,head[N],hcnt,ans[N]; 39 int n,m,k,L,R,sz,v; 40 int son[N],siz[N],id[N],tid; 41 int top[N],dep[N],fa[N],posi[N]; 42 struct Node{int to,nxt,v;}node[N<<3]; 43 struct Seg{int v,va;}seg[N<<2]; 44 inline void add(int x,int y,int v){ 45 node[hcnt].to=y,node[hcnt].nxt=head[x],node[hcnt].v=v,head[x]=hcnt++; 46 } 47 void dfs1(int u,int f,int deep){ 48 fa[u]=f,++siz[u],dep[u]=deep; 49 for(int e:V[u]){ 50 if(e==f)continue; 51 dfs1(e,u,deep+1);siz[u]+=siz[e]; 52 if(!son[u]||siz[son[u]]<siz[e])son[u]=e; 53 } 54 } 55 void dfs2(int u,int tp){ 56 id[u]=++tid,posi[tid]=u,top[u]=tp; 57 if(!son[u])return; dfs2(son[u],tp); 58 for(int e:V[u])if(!id[e])dfs2(e,e); 59 } 60 void pushup(int rt){ 61 if(seg[rt<<1].v>seg[rt<<1|1].v)seg[rt]=seg[rt<<1]; 62 else if(seg[rt<<1].v<seg[rt<<1|1].v)seg[rt]=seg[rt<<1|1]; 63 else if(num[seg[rt<<1].va]<num[seg[rt<<1|1].va])seg[rt]=seg[rt<<1]; 64 else seg[rt]=seg[rt<<1|1]; 65 } 66 void update(int rt,int l,int r){ 67 if(l==r){seg[rt].v+=v;seg[rt].va=l;return;} 68 int mid=l+r>>1; 69 if(L<=mid)update(lson); 70 else update(rson); 71 pushup(rt); 72 } 73 void build(int rt,int l,int r){ 74 if(l==r){seg[rt].va=l;return;} 75 int mid=l+r>>1; 76 build(lson);build(rson); 77 } 78 int main(){ 79 int i,j,group,x,y,Case=0; 80 n=read(),m=read(); 81 mst(head,-1); 82 for(i=1;i<n;++i){ 83 x=read(),y=read(); 84 V[x].push_back(y); 85 V[y].push_back(x); 86 } 87 dfs1(1,1,1);dfs2(1,1); 88 for(i=1;i<=m;++i){ 89 x=read(),y=read();v=read(); 90 if(!M[v]){ 91 M[v]=++ncnt; 92 num[ncnt]=v; 93 } 94 v=M[v]; 95 while(top[x]!=top[y]){ 96 if(dep[top[x]]<dep[top[y]])swap(x,y); 97 L=id[top[x]],R=id[x]; 98 add(L,v,1);add(R+1,v,-1); 99 x=fa[top[x]]; 100 } 101 if(dep[x]<dep[y])swap(x,y); 102 L=id[y],R=id[x]; 103 add(L,v,1);add(R+1,v,-1); 104 } 105 build(1,1,m); 106 for(i=1;i<=n;++i){ 107 for(j=head[i];~j;j=node[j].nxt){ 108 L=node[j].to;v=node[j].v; 109 update(1,1,m); 110 } 111 ans[posi[i]]=num[seg[1].va]; 112 } 113 for(i=1;i<=n;++i)printf("%d\n",ans[i]); 114 return 0; 115 }
以上是关于bzoj 3307 雨天的尾巴的主要内容,如果未能解决你的问题,请参考以下文章