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;
    }
  • 相关阅读:
    转载-MongoDB 分片集群技术
    EXT4参数优化及测试---转载
    9.16周记
    PHP优化思路
    2018.09.10-拾遗
    周记8
    落地成盒-发快递
    周记7
    GTX log 6
    Gitlab Jenkins WebHook 持续集成配置踩坑记
  • 原文地址:https://www.cnblogs.com/Hansue/p/10369263.html
Copyright © 2011-2022 走看看