zoukankan      html  css  js  c++  java
  • 【嵊中模拟2019.02.01】【BZOJ1103】大都市meg

    题目链接

    题解

    设DFS序(栈操作序列)为$seq$,点$i$入栈位置为$u_{i}$,出栈位置为$v_{i}$。

    发现以$i$为根的子树的所有点的出入栈位置都在$u_{i}$和$v_{i}$之间。

    考虑设标记序列$mark$,令$forall iin [1,n], mark_{u_{i}}=1, mark_{v_{i}}=-1$,代表点$i$到父亲的这条边的影响,入栈时增加$1$,出站时增加$-1$

    若点$i$到父亲的这条边从土路被改为公路,则要消去这条边的影响,即$mark_{u_{i}}-1, mark_{v_{i}}+1$。

    用树状数组维护$mark$的前缀和序列,设为$sum$,则$sum_{i}$即为根到点$i$的路径上的边数,支持单点修改和区间查询。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
        int n;
    struct E{
        int to,nxt;
    }e[500003];
        int sum;
        int h[250003];
    void adde(int from,int to){
        sum++;
        e[sum].to=to;
        e[sum].nxt=h[from];
        h[from]=sum;
    }
        bool vis[250003];
        int seq[500003],cnt;
        int u[250003],v[250003];
    void dfs(int x){
        seq[++cnt]=x;    u[x]=cnt;
        int y;
        for(int i=h[x];i;i=e[i].nxt){
            y=e[i].to;
            if(vis[y])
                continue;
            vis[y]=1;
            dfs(y);
        }
        seq[++cnt]=x;    v[x]=cnt;
    }
        int t[500003];
    int lowbit(int p){
        return p&(-p);
    }
    void add(int p,int n,int x){
        while(p<=n){
            t[p]+=x;
            p+=lowbit(p);
        }
    }
    int fpre(int p){
        int ans=0;
        while(p){
            ans+=t[p];
            p-=lowbit(p);
        }
        return ans;
    }
        int m;
    int max(int x,int y){
        if(x>y)
            return x;
        return y;
    }
    int main(){
        freopen("data.in","r",stdin);
        freopen("data.out","w",stdout);
        scanf("%d",&n);
        sum=0;
        memset(h,0,sizeof(h));
        int x,y;
        for(int i=1;i<n;i++){
            scanf("%d%d",&x,&y);
            adde(x,y);    adde(y,x);
        }
        memset(vis,0,sizeof(vis));
        cnt=0;    vis[1]=1;
        dfs(1);
        memset(t,0,sizeof(t));
        for(int i=2;i<=n;i++){
            add(u[i],cnt,1);
            add(v[i],cnt,-1);
        }
        scanf("%d",&m);    getchar();
        char typ;
        int dlvcnt=0;
        for(;1;){
            typ=getchar();    getchar();
            scanf("%d",&x);    getchar();
            if(typ=='A'){
                scanf("%d",&y);    getchar();
                x=max(x,y);                
                add(u[x],cnt,-1);
                add(v[x],cnt,+1);
            }
            else {
                printf("%d
    ",fpre(u[x]));
                dlvcnt++;
                if(dlvcnt==m)
                    break;
            }
        }
        return 0;
    }
  • 相关阅读:
    HDU 1124 Factorial
    hdu 1690 Bus System
    hdu 1113 Word Amalgamation
    POJ 2482 Stars in Your Window
    hdu 1385 ZOJ 1456 Minimum Transport Cost(经典floyd)
    hdu 1907 John
    VMware 虚拟机 安装 UBuntu 9.10 命令模式转换成窗口模试
    #pragma CODE_SEG __NEAR_SEG NON_BANKED详解
    Ubuntu 下Hadoop 伪分布式 hadoop0.20.2.tar.gz 的安装
    文件拷贝代码以及疑问
  • 原文地址:https://www.cnblogs.com/Hansue/p/10369263.html
Copyright © 2011-2022 走看看