[SCOI2015]情报传递

洛谷

树剖

不知道大佬们疯狂用主席树为何

#include
#define re return
#define inc(i,l,r) for(int i=l;i<=r;++i)
using namespace std;
templateinline void rd(T&x)
{
    char c;bool f=0;
    while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
    x=c^48;
    while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
    if(f)x=-x;
}

const int maxn=200005;
int n,m,fa[maxn],hd[maxn];
int k;
struct node{
    int to,nt;
}e[maxn];

inline void add(int x,int y)
{
    e[++k].to=y;e[k].nt=hd[x];hd[x]=k;
}

int deep[maxn],siz[maxn],son[maxn];
inline void dfs(int x)
{
    siz[x]=1;
    for(int i=hd[x];i;i=e[i].nt)
    {
        int v=e[i].to;
        deep[v]=deep[x]+1;
        dfs(v);
        siz[x]+=siz[v];
        if(siz[v]>siz[son[x]])son[x]=v;
    }
}

int seg[maxn],top[maxn],rev[maxn],tot;

inline void dfs2(int x,int ftop)
{
    top[x]=ftop;
    seg[x]=++tot;
    rev[tot]=x;
    if(son[x])
    {
        dfs2(son[x],ftop);
        for(int i=hd[x];i;i=e[i].nt)
        {
            int v=e[i].to;
            if(!top[v])
            dfs2(v,v);
        }
    }
}

//------------------------

#define ls rt<<1
#define rs rt<<1|1
int sum[maxn<<2];
inline void pushup(int rt)
{
    sum[rt]=sum[ls]+sum[rs];
}
inline void modify(int rt,int l,int r,int pos)
{
    if(l==r)
    {
        sum[rt]=1;
        re ;
    }
    
    int mid=(l+r)>>1;
    if(pos<=mid)modify(ls,l,mid,pos);
    else modify(rs,mid+1,r,pos);
    pushup(rt);
}

inline int query(int rt,int l,int r,int x,int y)
{
    if(x<=l&&r<=y)
        re sum[rt];
    int mid=(l+r)>>1;
    if(y<=mid)re query(ls,l,mid,x,y);
    else if(x>mid)re query(rs,mid+1,r,x,y);
    else re query(ls,l,mid,x,y)+query(rs,mid+1,r,x,y);
}

struct nide{
    int type,x,y,c,id;
    
    inline bool operator<(nide xx)const 
    {
        if(c==xx.c)re type>xx.type;
        re c<xx.c;
    }
}opt[maxn];
int ans1[maxn],ans2[maxn];

int main()
{
    rd(n);
    int rt;
    inc(i,1,n)
    {
        rd(fa[i]);
        add(fa[i],i);
        if(!fa[i])rt=i;
    }
    dfs(rt);
    dfs2(rt,rt);
    //-----
    rd(m);
    int k,x,y,c,t;
    inc(i,1,m)
    {
        opt[i].id=i;
        rd(opt[i].type);
        if(opt[i].type==1)
        {
            rd(opt[i].x),rd(opt[i].y),rd(opt[i].c);
            opt[i].c=i-opt[i].c-1;
        }
        else 
            rd(opt[i].x),opt[i].c=i;
    }
    
    sort(opt+1,opt+m+1);
    
    inc(i,1,m)
    {
        if(opt[i].type==1)
        {
            x=opt[i].x,y=opt[i].y;
            while(top[x]!=top[y])
            {
                if(deep[top[x]]<deep[top[y]])swap(x,y);
                ans2[opt[i].id]+=query(1,1,n,seg[top[x]],seg[x]);
                x=fa[top[x]];
            }
            if(deep[x]>deep[y])swap(x,y);
            ans1[opt[i].id]=deep[opt[i].x]+deep[opt[i].y]-deep[x]-deep[x]+1;
            ans2[opt[i].id]+=query(1,1,n,seg[x],seg[y]);
        }
        else modify(1,1,n,seg[opt[i].x]);
    }
    
    inc(i,1,m)
    if(ans1[i])
    printf("%d %d\n",ans1[i],ans2[i]);
    re 0;
}
View Code

 

你可能感兴趣的:([SCOI2015]情报传递)