• bzoj1103 POI2007 大都市meg


    看了下noi的水题 然后第一次自己YY出dfs序这个东西(当然以前听别人讲过没写过)

    然后做了一道dfs序的水题

    做法:

    统计出一个点的dfs序,成为pos[i]和以该节点为子树的所有点中pos[i]的最大值en[i]

    然后用树状数组单点修改区间询问处理

    可以把询问的过程想象为一次dfs,走到一条边ans++,返回ans--,那么对于一个点我们add(pos[x],1) add(en[x]+1,-1)来模拟这个过程 也就是去掉分叉的影响,不妨加一个超级源连在1号点,那么每次都是通过一条边来到了这里,所以query(pos[i])就是通过的边数,然而超级源的边不能计算,所以ans--。

    对于修改,一条边会使他的子树里的所有点的答案都-1,所以add(pos[x],-1) add(en[x]+1,1)

    然而bzoj上不用手写栈

    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<algorithm>
    
    using namespace std;
    
    const int Maxn=250000+10;
    
    int pos[Maxn],en[Maxn],clk=0;
    
    struct Edge{
        int to;
        Edge*next;
        Edge(int to=0,Edge*next=0):to(to),next(next) {}
    }pool[Maxn*2],*fir[Maxn],*pis=pool;
    void AddEdge(int from,int to) {
        *pis=Edge(to,fir[from]);fir[from]=pis++;
        *pis=Edge(from,fir[to]);fir[to]=pis++;
    }
    int fa[Maxn];
    void dfs(int x) {
        pos[x]=++clk;
        for(Edge*p=fir[x];p;p=p->next) {
            int v=p->to;
            if(v==fa[x]) continue;
            fa[v]=x;
            dfs(v);
        }
        en[x]=clk;
    }    
    
    int C[Maxn],n;
    void add(int x,int d) {
        for(;0<x&&x<=n;x+=x&-x) C[x]+=d;
    }
    
    int query(int x) {
        int ret=0;
        for(;0<x&&x<=n;x-=x&-x) ret+=C[x];
        return ret;
    }
    
    int main() {
    #ifdef DEBUG
        freopen("in.txt","r",stdin);
    //    freopen("out.txt","w",stdout);
    #endif
    
        scanf("%d",&n);
        for(int i=1;i<n;i++) {
            int u,v;
            scanf("%d%d",&u,&v);
            AddEdge(u,v);
        }
        dfs(1); 
        for(int i=1;i<=n;i++) {
            add(pos[i],1);
            add(en[i]+1,-1);
        }
        int m;
        for(scanf("%d",&m);m;) {
            char opt;
            int x,y;
            while(opt=getchar(),opt!='A'&&opt!='W');
            if(opt=='A') {
                scanf("%d%d",&x,&y);
                if(fa[y]==x) swap(x,y);
                add(pos[x],-1);
                add(en[x]+1,1);
            }else {
                scanf("%d",&x);
                printf("%d
    ",query(pos[x])-1);
                m--;
            }
        }
        
        return 0;
    }
    View Code
  • 相关阅读:
    EventDemo——演示事件流
    数组的深复制和浅复制
    Loader类和LoaderInfo类
    几个不同颜色方框——事件流
    自定义事件类的方法——实现接口
    [转帖]ModelSim+Synplify+Quartus的Altera FPGA的仿真与验证
    [转帖]2011年最新企业offer(待遇)比较
    [转帖]引用 利用ModelSim进行的功能仿真,综合后仿真,时序仿真
    [转帖]VHDL中Configuration
    [转帖]ModelSim+Debussy仿真(Verilog)
  • 原文地址:https://www.cnblogs.com/showson/p/4655529.html
Copyright © 2020-2023  润新知