bzoj3626 [LNOI2014]LCA
2017-11-06 14:08
369 查看
又是差分,然后利用标记求和求某对点lca的dep
比如求a,b lca的dep,则把根到a的所有点标记,再在根到b的路径上求和,
于是就可以树剖了。前缀和差分一下就好了。
想打主席树,没有实现,
在线主席树具体可见[Troywar]。
bzoj3626
比如求a,b lca的dep,则把根到a的所有点标记,再在根到b的路径上求和,
于是就可以树剖了。前缀和差分一下就好了。
想打主席树,没有实现,
在线主席树具体可见[Troywar]。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> #define N 50050 #define mod 201314 using namespace std; int n,m; int e=1,head ; struct edge{int v,next;}ed ; void add(int u,int v){ ed[e].v=v; ed[e].next=head[u]; head[u]=e++; } struct data{int pos,x,id,val;}d[N*2]; bool cmp(data a,data b){ return a.pos<b.pos; } int dep ,size ,fa ,son ,top ,tot,id ; void dfs1(int x,int d){ dep[x]=d;size[x]=1; for(int i=head[x];i;i=ed[i].next){ int v=ed[i].v; if(v==fa[x])continue; fa[v]=x; dfs1(v,d+1); size[x]+=size[v]; if(size[v]>size[son[x]])son[x]=v; } } void dfs2(int x,int t){ top[x]=t;id[x]=++tot; if(son[x])dfs2(son[x],t); for(int i=head[x];i;i=ed[i].next){ int v=ed[i].v; if(v==fa[x]||v==son[x])continue; dfs2(v,v); } } int sum[4*N],lazy[4*N]; inline void pushup(int rt){ sum[rt]=sum[rt<<1]+sum[rt<<1|1]; } inline void pushdown(int rt,int l,int r){ if(lazy[rt]){ int mid=(l+r)>>1; sum[rt<<1]+=lazy[rt]*(mid-l+1); lazy[rt<<1]+=lazy[rt]; sum[rt<<1|1]+=lazy[rt]*(r-mid); lazy[rt<<1|1]+=lazy[rt]; lazy[rt]=0; } } void update(int rt,int l,int r,int x,int y){ if(x<=l&&r<=y){ sum[rt]+=(r-l+1); lazy[rt]++; return ; } pushdown(rt,l,r); int mid=(l+r)>>1; if(x<=mid)update(rt<<1,l,mid,x,y); if(y>mid)update(rt<<1|1,mid+1,r,x,y); pushup(rt); } int query(int rt,int l,int r,int x,int y){ if(x<=l&&r<=y)return sum[rt]; pushdown(rt,l,r); int mid=(l+r)>>1,ans=0; if(x<=mid)ans+=query(rt<<1,l,mid,x,y); if(y>mid)ans+=query(rt<<1|1,mid+1,r,x,y); return ans; } void UPDATE(int x){ while(x){ update(1,1,n,id[top[x]],id[x]); x=fa[top[x]]; } } int QUERY(int x){ int ans=0; while(x){ ans+=query(1,1,n,id[top[x]],id[x]); x=fa[top[x]]; } return ans; } int ans ; int main(){ scanf("%d%d",&n,&m); for(int i=2,x;i<=n;i++){scanf("%d",&x);add(x+1,i);} dfs1(1,1); dfs2(1,1); for(int i=1,l,r,p;i<=m;i++){ scanf("%d%d%d",&l,&r,&p);l++;r++;p++; 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; d[i*2].pos=r;d[i*2].x=p;d[i*2].id=i;d[i*2].val=1; } sort(d+1,d+2*m+1,cmp); for(int i=1,j=1;i<=n;i++){ UPDATE(i); while(j<=2*m&&d[j].pos<i)j++; while(j<=2*m&&d[j].pos==i){ ans[d[j].id]+=d[j].val*QUERY(d[j].x); j++; } if(j>2*m)break; } for(int i=1;i<=m;i++) printf("%d\n",ans[i]%mod); return 0; }
bzoj3626
相关文章推荐
- BZOJ 3626 [LNOI2014]LCA
- AC日记——[LNOI2014]LCA bzoj 3626
- [BZOJ3626][LNOI2014]LCA(离线+链剖)
- bzoj 3626: [LNOI2014]LCA(树链剖分+离线+差分)
- [bzoj3626][LNOI2014]LCA 树链剖分
- [BZOJ3626][LNOI2014][树链剖分][差分][离线处理]LCA
- BZOJ 3626: [LNOI2014]LCA( 树链剖分 + 离线 )
- bzoj3626 [LNOI2014]LCA
- [BZOJ 3626] [LNOI2014] LCA 【树链剖分 + 离线 + 差分询问】
- BZOJ3626: [LNOI2014]LCA
- 【BZOJ3626】[LNOI2014]LCA 离线+树链剖分+线段树
- BZOJ 3626: [LNOI2014]LCA 树链剖分 询问差分
- bzoj 3626: [LNOI2014]LCA
- bzoj 3626 [LNOI2014]LCA(离线处理+树链剖分,线段树)
- BZOJ3626 : [LNOI2014]LCA
- 【BZOJ 3626】 [LNOI2014]LCA【在线+主席树+树剖】
- [BZOJ3626][LNOI2014]LCA
- BZOJ3626 [LNOI2014]LCA(树链剖分)
- BZOJ3626 [LNOI2014]LCA
- BZOJ[3626][LNOI2014]LCA 树链剖分+线段树