首页 > 代码库 > AC日记——「SCOI2015」情报传递 LiBreOJ 2011

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

#2011. 「SCOI2015」情报传递

 

思路:

  可持久化树状数组模板;

 

代码:

#include <bits/stdc++.h>using namespace std;#define maxn 200005#define maxm maxn*100int 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