bzoj3626 [LNOI2014]LCA
Posted Ren_Ivan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj3626 [LNOI2014]LCA相关的知识,希望对你有一定的参考价值。
又是差分,然后利用标记求和求某对点lca的dep
比如求a,b lca的dep,则把根到a的所有点标记,再在根到b的路径上求和,
于是就可以树剖了。前缀和差分一下就好了。
想打主席树,没有实现,
在线主席树具体可见[Troywar]。
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<cmath> 6 #define N 50050 7 #define mod 201314 8 using namespace std; 9 int n,m; 10 int e=1,head[N]; 11 struct edge{int v,next;}ed[N]; 12 void add(int u,int v){ 13 ed[e].v=v; 14 ed[e].next=head[u]; 15 head[u]=e++; 16 } 17 struct data{int pos,x,id,val;}d[N*2]; 18 bool cmp(data a,data b){ 19 return a.pos<b.pos; 20 } 21 int dep[N],size[N],fa[N],son[N],top[N],tot,id[N]; 22 void dfs1(int x,int d){ 23 dep[x]=d;size[x]=1; 24 for(int i=head[x];i;i=ed[i].next){ 25 int v=ed[i].v; 26 if(v==fa[x])continue; 27 fa[v]=x; dfs1(v,d+1); 28 size[x]+=size[v]; 29 if(size[v]>size[son[x]])son[x]=v; 30 } 31 } 32 void dfs2(int x,int t){ 33 top[x]=t;id[x]=++tot; 34 if(son[x])dfs2(son[x],t); 35 for(int i=head[x];i;i=ed[i].next){ 36 int v=ed[i].v; 37 if(v==fa[x]||v==son[x])continue; 38 dfs2(v,v); 39 } 40 } 41 int sum[4*N],lazy[4*N]; 42 inline void pushup(int rt){ 43 sum[rt]=sum[rt<<1]+sum[rt<<1|1]; 44 } 45 inline void pushdown(int rt,int l,int r){ 46 if(lazy[rt]){ 47 int mid=(l+r)>>1; 48 sum[rt<<1]+=lazy[rt]*(mid-l+1); 49 lazy[rt<<1]+=lazy[rt]; 50 sum[rt<<1|1]+=lazy[rt]*(r-mid); 51 lazy[rt<<1|1]+=lazy[rt]; 52 lazy[rt]=0; 53 } 54 } 55 void update(int rt,int l,int r,int x,int y){ 56 if(x<=l&&r<=y){ 57 sum[rt]+=(r-l+1); 58 lazy[rt]++; 59 return ; 60 } 61 pushdown(rt,l,r); 62 int mid=(l+r)>>1; 63 if(x<=mid)update(rt<<1,l,mid,x,y); 64 if(y>mid)update(rt<<1|1,mid+1,r,x,y); 65 pushup(rt); 66 } 67 int query(int rt,int l,int r,int x,int y){ 68 if(x<=l&&r<=y)return sum[rt]; 69 pushdown(rt,l,r); 70 int mid=(l+r)>>1,ans=0; 71 if(x<=mid)ans+=query(rt<<1,l,mid,x,y); 72 if(y>mid)ans+=query(rt<<1|1,mid+1,r,x,y); 73 return ans; 74 } 75 void UPDATE(int x){ 76 while(x){ 77 update(1,1,n,id[top[x]],id[x]); 78 x=fa[top[x]]; 79 } 80 } 81 int QUERY(int x){ 82 int ans=0; 83 while(x){ 84 ans+=query(1,1,n,id[top[x]],id[x]); 85 x=fa[top[x]]; 86 } 87 return ans; 88 } 89 int ans[N]; 90 int main(){ 91 scanf("%d%d",&n,&m); 92 for(int i=2,x;i<=n;i++){scanf("%d",&x);add(x+1,i);} 93 dfs1(1,1); 94 dfs2(1,1); 95 for(int i=1,l,r,p;i<=m;i++){ 96 scanf("%d%d%d",&l,&r,&p);l++;r++;p++; 97 d[i*2-1].pos=l-1;d[i*2-1].x=p;d[i*2-1].id=i;d[i*2-1].val=-1; 98 d[i*2].pos=r;d[i*2].x=p;d[i*2].id=i;d[i*2].val=1; 99 } 100 sort(d+1,d+2*m+1,cmp); 101 for(int i=1,j=1;i<=n;i++){ 102 UPDATE(i); 103 while(j<=2*m&&d[j].pos<i)j++; 104 while(j<=2*m&&d[j].pos==i){ 105 ans[d[j].id]+=d[j].val*QUERY(d[j].x); 106 j++; 107 } 108 if(j>2*m)break; 109 } 110 for(int i=1;i<=m;i++) 111 printf("%d\\n",ans[i]%mod); 112 return 0; 113 }
以上是关于bzoj3626 [LNOI2014]LCA的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ 3626: [LNOI2014]LCA [树链剖分 离线|主席树]