AC日记——「SCOI2015」情报传递 LiBreOJ 2011

Posted Only U - IU

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AC日记——「SCOI2015」情报传递 LiBreOJ 2011相关的知识,希望对你有一定的参考价值。

#2011. 「SCOI2015」情报传递

 

思路:

  可持久化树状数组模板;

 

代码:

#include <bits/stdc++.h>
using namespace std;
#define maxn 200005
#define maxm maxn*100
int deep[maxn],f[maxn],id[maxn],top[maxn],cnt,soot;
int head[maxn],V[maxn],E[maxn],lar[maxn],size[maxn];
int val[maxm],root[maxn],ch[maxm][2],tot,Tl,Tr,n,m,Ans;
inline void in(int &now)
{
    char Cget=getchar();now=0;
    while(Cget>9||Cget<0)Cget=getchar();
    while(Cget>=0&&Cget<=9)
    {
        now=now*10+Cget-0;
        Cget=getchar();
    }
}
void build(int &now,int l,int r)
{
    now=++tot;
    if(l==r) return;int mid=l+r>>1;
    build(ch[now][0],l,mid);
    build(ch[now][1],mid+1,r);
}
void add(int &now,int pre,int l,int r,int to,int x)
{
    now=++tot,val[now]=val[pre]+x;
    if(l==r) return;int mid=l+r>>1;
    if(to<=mid) add(ch[now][0],ch[pre][0],l,mid,to,x),ch[now][1]=ch[pre][1];
    else add(ch[now][1],ch[pre][1],mid+1,r,to,x),ch[now][0]=ch[pre][0];
}
int lowbit(int x)
{
    return x&(-x);
}
void add(int to1,int to2,int x)
{
    while(to1<=n) add(root[to1],root[to1],1,m,to2,x),to1+=lowbit(to1);
}
void dfs1(int now)
{
    deep[now]=deep[f[now]]+1,size[now]=1;
    for(int i=head[now];i;i=E[i])
    {
        dfs1(V[i]),size[now]+=size[V[i]];
        if(size[lar[now]]<size[V[i]]) lar[now]=V[i];
    }
}
void dfs2(int now,int chain)
{
    top[now]=chain,id[now]=++cnt;
    root[id[now]]=root[0];
    if(lar[now])
    {
        dfs2(lar[now],chain);
        for(int i=head[now];i;i=E[i])
        {
            if(V[i]==lar[now]) continue;
            dfs2(V[i],V[i]);
        }
    }
}
int query(int now,int l,int r)
{
    if(l>=Tl&&r<=Tr) return val[now];
    int mid=l+r>>1,res=0;
    if(Tl<=mid) res+=query(ch[now][0],l,mid);
    if(Tr>mid) res+=query(ch[now][1],mid+1,r);
    return res;
}
int query(int l,int r)
{
    l--;int res=0;
    while(r) res+=query(root[r],1,m),r-=lowbit(r);
    while(l) res-=query(root[l],1,m),l-=lowbit(l);
    return res;
}
int query(int x,int y,int tl,int tr)
{
    int res=0;Tl=tl,Tr=tr;
    while(top[x]!=top[y])
    {
        if(deep[top[x]]<deep[top[y]]) res+=query(id[top[y]],id[y]),y=f[top[y]];
        else res+=query(id[top[x]],id[x]),x=f[top[x]];
    }
    if(deep[x]>deep[y]) swap(x,y);
    res+=query(id[x],id[y]);
    return res;
}
int lca(int x,int y)
{
    while(top[x]!=top[y])
    {
        if(deep[top[x]]>deep[top[y]]) x=f[top[x]];
        else y=f[top[y]];
    }
    return deep[x]<deep[y]?deep[x]:deep[y];
}
int main()
{
    freopen("data.txt","r",stdin);
    freopen("data.out","w",stdout);
    in(n);int op,u,v,c;
    for(int i=1;i<=n;i++)
    {
        in(f[i]);
        if(!f[i]) soot=i;
        else E[i]=head[f[i]],V[i]=i,head[f[i]]=i;
    }
    in(m);
    build(root[0],1,m),dfs1(soot),dfs2(soot,soot);
    for(int i=1;i<=m;i++)
    {
        in(op);
        if(op==2)in(u),add(id[u],i,1);
        else
        {
            in(u),in(v),in(c),Ans=deep[u]+deep[v]-2*lca(u,v)+1;
            printf("%d ",Ans);
            if(i-c-1>=1) printf("%d\n",query(u,v,1,i-c-1));
            else printf("0\n");
        }
    }
    return 0;
}

 

以上是关于AC日记——「SCOI2015」情报传递 LiBreOJ 2011的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ [Scoi2015]情报传递

BZOJ4448[Scoi2015]情报传递 主席树+LCA

BZOJ_4448_[Scoi2015]情报传递_主席树

bzoj 4448: [Scoi2015]情报传递

[SCOI2015]情报传递[树剖+主席树]

AC日记——「SCOI2015」国旗计划 LiBreOJ 2007