zoukankan      html  css  js  c++  java
  • 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
    ",query(u,v,1,i-c-1));
                else printf("0
    ");
            }
        }
        return 0;
    }
  • 相关阅读:
    img标签中alt属性与title属性在seo的作用-摘自网友
    C# 从补码中获取有符号数的实际数值
    you need to load the kernel first
    桌面远程访问
    供应商通过向日葵访问公司外网办公电脑,通过办公电脑访问内网内生产用电脑
    配置交换机口可以上外网
    抠图和不失真的改变图形大小
    用机房现有双网口电脑添加监控
    服务器配置IP
    在DELL服务器上安装windows2012 r2服务器系统
  • 原文地址:https://www.cnblogs.com/IUUUUUUUskyyy/p/7071529.html
Copyright © 2011-2022 走看看