[LNOI2014]LCA

 

https://www.luogu.org/problemnew/show/P4211

人生中第一道黑题!!!我觉得差不多紫题难度吧qaq

 

题意:

 

思路:

 

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
inline int read(){
    int x=0;
    char ch=getchar();
    while(ch<'0'||ch>'9') ch=getchar();
    while(ch>='0'&&ch<='9'){
        x=(x<<3)+(x<<1)+ch-48;
        ch=getchar();
    }
    return x;
}
const int maxn=5e4+4;
int head[maxn],siz[maxn],fa[maxn],son[maxn],top[maxn],seg[maxn],rev[maxn],dep[maxn];
int n,m,cnt=0;
struct node{
    int to,next;
}e[maxn];
inline void add(int u,int v){
    e[cnt].to=v;e[cnt].next=head[u];head[u]=cnt++;
}
inline void dfs1(int u,int f){
    siz[u]=1;
    fa[u]=f;
    dep[u]=dep[f]+1;
    for(int i=head[u];i!=-1;i=e[i].next){
        int v=e[i].to;
        if(v==f)  continue;
        dfs1(v,u);
        siz[u]+=siz[v];
        if(siz[v]>siz[son[u]]) son[u]=v;
    }
}
inline void dfs2(int u,int t){
    top[u]=t;seg[u]=++seg[0];rev[seg[0]]=u;
    if(!son[u]) return;
    dfs2(son[u],t);
    for(int i=head[u];i!=-1;i=e[i].next){
        int v=e[i].to;
        if(!top[v]) dfs2(v,v);
    }
}
struct xds{
    int l,r,tag,val;
}tr[maxn<<2];
int a[maxn],b[maxn];
inline void build(int k,int l,int r){
    tr[k].l=l,tr[k].r=r;
    if(l==r) return;
    int mid=l+r>>1;
    build(k<<1,l,mid);
    build(k<<1|1,mid+1,r);
}
vector<pair<int,int> >ve[maxn];
inline void pushdown(int k){
    tr[k<<1].val=(tr[k<<1].val+tr[k].tag*(tr[k<<1].r-tr[k<<1].l+1))%201314;
    tr[k<<1|1].val=(tr[k<<1|1].val+tr[k].tag*(tr[k<<1|1].r-tr[k<<1|1].l+1))%201314;
    tr[k<<1].tag+=tr[k].tag;
    tr[k<<1|1].tag+=tr[k].tag;
    tr[k].tag=0;
}
inline void update(int k,int x,int y){
    int l=tr[k].l,r=tr[k].r;
    if(l==x&&y==r){
        tr[k].val=(tr[k].val+r-l+1)%201314;tr[k].tag++;
        return;
    }
    pushdown(k);
    tr[k].val=(tr[k].val+y-x+1);
    int mid=l+r>>1;
    if(x>mid) update(k<<1|1,x,y);
    else if(y<=mid) update(k<<1,x,y);
    else {update(k<<1,x,mid);update(k<<1|1,mid+1,y);}
    tr[k].val=(tr[k<<1].val+tr[k<<1|1].val)%201314;
}
inline int query(int k,int x,int y){
    int l=tr[k].l,r=tr[k].r;
    if(l==x&&y==r){
        return tr[k].val;
    }
    pushdown(k);
    int mid=l+r>>1;
    int sum=0;
    if(x>mid) sum=query(k<<1|1,x,y);
    else if(y<=mid) sum=query(k<<1,x,y);
    else sum=query(k<<1,x,mid)+query(k<<1|1,mid+1,y);
    tr[k].val=(tr[k<<1].val+tr[k<<1|1].val)%201314;
    return sum;
}
inline void change(int x,int y){
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]]) swap(x,y);
        update(1,seg[top[x]],seg[x]);
        x=fa[top[x]];
    }
    if(dep[x]>dep[y]) swap(x,y);
    update(1,seg[x],seg[y]);
}
inline int chaxun(int x,int y){
    int sum=0;
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]]) swap(x,y);
        sum=(sum+query(1,seg[top[x]],seg[x]))%201314;
        x=fa[top[x]];
    }
    if(dep[x]>dep[y]) swap(x,y);
    sum=(sum+query(1,seg[x],seg[y]))%201314;
    return sum;
}
int main(){
    n=read();int q=read();
    memset(head,-1,sizeof(head));
    memset(a,-1,sizeof(a));
    for(int i=1;i<n;i++){
        int x=read();
        add(x+1,i+1);
    }
    dfs1(1,0);
    dfs2(1,1);
    build(1,1,n);
    for(int i=1;i<=q;i++){
        int x=read(),y=read(),z=read();
        x++,y++,z++;
        ve[x-1].push_back(make_pair(i,z));
        ve[y].push_back(make_pair(i,z));
    }
    for(int j=0;j<ve[0].size();j++) a[ve[0][j].first]=0;
    for(int i=1;i<=n;i++){
        change(1,i);
        for(int j=0;j<ve[i].size();j++){
            if(a[ve[i][j].first]==-1) a[ve[i][j].first]=chaxun(1,ve[i][j].second);
            else b[ve[i][j].first]=chaxun(1,ve[i][j].second);
        }
    }
    for(int i=1;i<=q;i++)
        printf("%d\n",(b[i]-a[i]+201314)%201314);
}

 

posted @ 2019-01-06 21:05  WiFiMonster  阅读(145)  评论(0编辑  收藏  举报