[JLOI2014]松鼠的新家-树链剖分
Posted wangyifan124
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[JLOI2014]松鼠的新家-树链剖分相关的知识,希望对你有一定的参考价值。
最开始的时候我在写线段树部分的时候还打了一个build,后来一想,打个球球大作战的build啊!!!有个锤子的用啊!!!
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn = 3e6+5; 4 int n; 5 int e,begin[maxn],next[maxn],to[maxn],a[maxn]; 6 int tree[maxn<<2],lazy[maxn<<2]; 7 int son[maxn],father[maxn],id[maxn],cnt,deep[maxn],size[maxn],top[maxn]; 8 int res; 9 inline int read(){ 10 int s=0,w=1; 11 char ch=getchar(); 12 while(ch<=‘0‘||ch>‘9‘){if(ch==‘-‘)w=-1;ch=getchar();} 13 while(ch>=‘0‘&&ch<=‘9‘) s=s*10+ch-‘0‘,ch=getchar(); 14 return s*w; 15 } 16 inline void add(int x,int y){ 17 to[++e] = y; 18 next[e] = begin[x]; 19 begin[x] = e; 20 } 21 inline void pushup(int root){ 22 tree[root] = tree[root<<1]+tree[root<<1|1]; 23 } 24 inline void pushdown(int root,int pos){ 25 lazy[root<<1] += lazy[root]; 26 lazy[root<<1|1] += lazy[root]; 27 tree[root<<1] += lazy[root]*(pos-(pos>>1)); 28 tree[root<<1|1] += lazy[root]*(pos>>1); 29 lazy[root] = 0; 30 } 31 inline void query(int root,int l,int r,int al,int ar){ 32 if(al <= l && ar >= r){ 33 res += tree[root]; 34 return; 35 } 36 if(lazy[root])pushdown(root,r-l+1); 37 int mid = l+r>>1; 38 if(al <= mid)query(root<<1,l,mid,al,ar); 39 if(ar > mid)query(root<<1|1,mid+1,r,al,ar); 40 } 41 inline void update(int root,int l,int r,int al,int ar,int k){ 42 if(al <= l && ar >= r){ 43 lazy[root] += k; 44 tree[root] += k*(r-l+1); 45 return; 46 } 47 if(lazy[root])pushdown(root,r-l+1); 48 int mid = l+r>>1; 49 if(al <= mid)update(root<<1,l,mid,al,ar,k); 50 if(ar > mid)update(root<<1|1,mid+1,r,al,ar,k); 51 pushup(root); 52 } 53 inline void update_range(int x,int y,int k){ 54 while(top[x] != top[y]){ 55 if(deep[top[x]] < deep[top[y]])swap(x,y); 56 update(1,1,n,id[top[x]],id[x],k); 57 x = father[top[x]]; 58 } 59 if(deep[x] > deep[y])swap(x,y); 60 update(1,1,n,id[x],id[y],k); 61 } 62 inline void dfs1(int x,int fa,int dep){ 63 deep[x] = dep; 64 father[x] = fa; 65 size[x] = 1; 66 int maxson = -1; 67 for(int i = begin[x];i;i = next[i]){ 68 int y = to[i]; 69 if(y == fa)continue; 70 dfs1(y,x,dep+1); 71 size[x] += size[y]; 72 if(size[y] > maxson)son[x] = y,maxson = size[y]; 73 } 74 } 75 inline void dfs2(int x,int topf){ 76 id[x] = ++cnt; 77 top[x] = topf; 78 if(!son[x])return; 79 dfs2(son[x],topf); 80 for(int i = begin[x];i;i = next[i]){ 81 int y = to[i]; 82 if(y == father[x] || y == son[x])continue; 83 dfs2(y,y); 84 } 85 } 86 int main(){ 87 n = read(); 88 for(int i = 1;i <= n;i++)a[i] = read(); 89 for(int i = 1,x,y;i < n;i++){ 90 x = read(); 91 y = read(); 92 add(x,y); 93 add(y,x); 94 } 95 dfs1(1,0,1); 96 dfs2(1,1); 97 for(int i = 1;i < n;i++){ 98 update_range(a[i],a[i+1],1); 99 update_range(a[i+1],a[i+1],-1); 100 } 101 for(int i = 1;i <= n;i++)res = 0,query(1,1,n,id[i],id[i]),printf("%d ",res); 102 return 0; 103 }
以上是关于[JLOI2014]松鼠的新家-树链剖分的主要内容,如果未能解决你的问题,请参考以下文章