• bzoj 2440 dfs序


      首先我们可以做一遍dfs,用一个队列记录每个点进出的顺序,当每个点访问的时候que[tot++]=x,记为in[x],当结束dfs的时候que[tot++]=x,记为out[x],这样处理出来的队列,如果我们将一个数的进队赋值为1,出队赋值为-1,那么假设我们需要询问1-x的链中共有多少个点,答案就是这个队列前int[x]项,所以我们开始dfs1处理出来in,out数组,然后用树状数组维护这个队列,就行了。

      

    /**************************************************************
        Problem: 1103
        User: BLADEVIL
        Language: C++
        Result: Accepted
        Time:4680 ms
        Memory:11300 kb
    ****************************************************************/
     
    //By BLADEVIL
    #include <cstdio>
    #define maxn 250010
     
    using namespace std;
     
    int n,l,tot;
    int last[maxn],other[maxn],pre[maxn],in[maxn],out[maxn],w[maxn<<1];
    char c[10];
     
    void change(int x,int y)
    {
        while (x<=(n<<1))
        {
            w[x]+=y;
            x+=x&(-x);
        }
    }
     
    int ask(int x)
    {
        int ans=0;
        while (x)
        {
            ans+=w[x];
            x-=x&(-x);
        }
        return ans;
    }
     
    void connect(int x,int y)
    {
        pre[++l]=last[x];
        last[x]=l;
        other[l]=y;
    }
     
    void dfs(int x,int fa)
    {
        in[x]=++tot;
        for (int q=last[x];q;q=pre[q])
        {
            if (other[q]==fa) continue;
            dfs(other[q],fa);
        }
        out[x]=++tot;
    }
     
    int main()
    {
        scanf("%d",&n);
        for (int i=1;i<n;i++) 
        {
            int x,y;
            scanf("%d%d",&x,&y);
            connect(x,y);
        }
        dfs(1,-1);
        //for (int i=1;i<=n;i++) printf("%d %d %d
    ",i,in[i],out[i]);
        for (int i=2;i<=n;i++) change(in[i],1),change(out[i],-1);
        //for (int i=2;i<=2*n;i++) printf("%d ",ask(i)-ask(i-1)); printf("
    ");
        int m;
        scanf("%d",&m);
        m+=n-1;
        while (m--)
        {
            int x,y;
            scanf("%s",&c);
            if (c[0]=='W')
            {
                scanf("%d",&x);
                //printf("x %d
    ",in[x]);
                printf("%d
    ",ask(in[x]));
            } else
            {
                scanf("%d%d",&x,&y);
                y=(x>y)?x:y;
                change(in[y],-1); change(out[y],1);
                //printf(" %d %d
    ",in[y],out[y]);
            }
        }
        return 0;
    }
  • 相关阅读:
    英语口语交际最常用短语
    家庭英语口语800句
    C#基础概念二十五问
    英语常用日常交际用语
    系统进程总结
    虚拟键盘驱动程序
    系统程序员成长计划拥抱变化(上)
    系统程序员成长计划谁动了你的隐私(上)
    系统程序员成长计划谁动了你的隐私(下)
    系统程序员成长计划Write once, run anywhere(WORA)(上)
  • 原文地址:https://www.cnblogs.com/BLADEVIL/p/3554294.html
Copyright © 2020-2023  润新知