• [SCOI2015]情报传递


    洛谷

    树剖

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

    #include<bits/stdc++.h>
    #define re return
    #define inc(i,l,r) for(int i=l;i<=r;++i)
    using namespace std;
    template<typename T>inline 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
    ",ans1[i],ans2[i]);
        re 0;
    }
    View Code
  • 相关阅读:
    JavaScript内置对象String对象下常用的方法
    JavaScript内置对象String对象
    JavaScript内置对象Math产生一个16进制的随机颜色值
    JavaScript内置对象Math查询一组数中的最大值
    JavaScript内置对象Date常用方法总结
    JavaScript内置对象Date常用函数
    JavaScript内置对象Date----格式化时间
    C++学习笔记30:模板与型式参数化
    C++学习笔记29:运行期型式信息2
    C++学习笔记28:运行期型式信息
  • 原文地址:https://www.cnblogs.com/lsyyy/p/11725071.html
Copyright © 2020-2023  润新知