BZOJ3626 LNOI2014LCA(树链剖分+主席树)
开店简化版。
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; int read() { int x=0,f=1;char c=getchar(); while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();} while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } #define N 50010 #define P 201314 int n,m,q,t=0,a[N],p[N]; int fa[N],top[N],id[N],size[N],son[N],cnt=0; struct data{int to,nxt; }edge[N<<1]; int root[N]; struct data2{int l,r,tag,x; }tree[N<<7]; void addedge(int x,int y){t++;edge[t].to=y,edge[t].nxt=p[x],p[x]=t;} bool cmp(const int&x,const int&y) { return a[x]<a[y]; } void dfs1(int k) { size[k]=1; for (int i=p[k];i;i=edge[i].nxt) { fa[edge[i].to]=k; dfs1(edge[i].to); size[k]+=size[edge[i].to]; if (size[edge[i].to]>size[son[k]]) son[k]=edge[i].to; } } void dfs2(int k,int from) { top[k]=from;id[k]=++cnt; if (son[k]) dfs2(son[k],from); for (int i=p[k];i;i=edge[i].nxt) if (edge[i].to!=son[k]) dfs2(edge[i].to,edge[i].to); } void inc(int &x,int y){x+=y;if (x>=P) x-=P;} void add(int &k,int l,int r,int x,int y) { if (x>y) return; tree[++cnt]=tree[k];k=cnt; inc(tree[k].x,y-x+1); if (l==x&&r==y){tree[k].tag++;return;} int mid=l+r>>1; if (y<=mid) add(tree[k].l,l,mid,x,y); else if (x>mid) add(tree[k].r,mid+1,r,x,y); else add(tree[k].l,l,mid,x,mid),add(tree[k].r,mid+1,r,mid+1,y); } int query(int k,int l,int r,int x,int y,int tag) { if (x>y) return 0; if (l==x&&r==y) return (tree[k].x+1ll*(y-x+1)*tag%P)%P; tag+=tree[k].tag; int mid=l+r>>1; if (y<=mid) return query(tree[k].l,l,mid,x,y,tag); else if (x>mid) return query(tree[k].r,mid+1,r,x,y,tag); else return (query(tree[k].l,l,mid,x,mid,tag)+query(tree[k].r,mid+1,r,mid+1,y,tag))%P; } void modify(int i,int x) { while (x) { add(root[i],1,n,id[top[x]],id[x]); x=fa[top[x]]; } } int getans(int r,int l,int x) { int s=0; while (x) { inc(s,query(root[r],1,n,id[top[x]],id[x],0)-query(root[l],1,n,id[top[x]],id[x],0)); if (s<0) s+=P; x=fa[top[x]]; } return s; } int main() { #ifndef ONLINE_JUDGE freopen("bzoj3626.in","r",stdin); freopen("bzoj3626.out","w",stdout); const char LL[]="%I64d\n"; #else const char LL[]="%lld\n"; #endif n=read(),q=read(); for (int i=2;i<=n;i++) { int x=read(); addedge(x+1,i); } dfs1(1); dfs2(1,1); cnt=0; for (int i=1;i<=n;i++) { root[i]=root[i-1]; modify(i,i); } for (int i=1;i<=q;i++) { int l=read()+1,r=read()+1,x=read()+1; printf("%d\n",getans(r,l-1,x)); } return 0; }