zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    C# this关键字的四种用法
    MVC Html.AntiForgeryToken() 防止CSRF攻击
    简单的C#网络爬虫
    string format的各类格式及用法
    选取两个有序数组中最大的K个值,降序存入另一个数组中
    程序员面试:青蛙跳台阶问题(变态跳台阶)
    贪心算法,递归算法,动态规划算法比较与总结
    storm简介[ZZ]
    逻辑回归:使用SGD(Stochastic Gradient Descent)进行大规模机器学习
    mahout分类
  • 原文地址:https://www.cnblogs.com/BLADEVIL/p/3554294.html
Copyright © 2011-2022 走看看