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;
}

 

posted @ 2018-08-03 10:19  Gloid  阅读(195)  评论(0编辑  收藏  举报