zoukankan      html  css  js  c++  java
  • 【BZOJ 1103】[POI2007]大都市meg

    【链接】 我是链接,点我呀:)
    【题意】

    在这里输入题意

    【题解】

    dfs序 进入的位置设为1出去的设为-1则某个点进去的位置的dfs序的前缀和就是这个点到根节点的路径数。 (可以巧妙的把那些分叉路径去掉。 修改成公路后。就把下面的那个点(深度高的)的进入和出去的值都设置为0 用线段树维护区间和。 (可以用树状数组.

    【代码】

    #include <bits/stdc++.h>
    #define LL long long
    #define rep1(i,a,b) for (int i = a;i <= b;i++)
    #define rep2(i,a,b) for (int i = a;i >= b;i--)
    #define all(x) x.begin(),x.end()
    #define pb push_back
    #define lson l,mid,rt<<1
    #define rson mid+1,r,rt<<1|1
    using namespace std;
    
    const double pi = acos(-1);
    const int dx[4] = {0,0,1,-1};
    const int dy[4] = {1,-1,0,0};
    
    const int N = 25e4;
    const int NN = 50e4;
    
    int n,cnt,c[NN+10],_in[N+10],_out[N+10],sum[NN*4],_dep[N+10];
    vector<int> g[N+10];
    
    void dfs(int x,int fa,int dep){
        cnt++;
        c[cnt] = 1;
        _in[x] = cnt;
        _dep[x] = dep;
    
        for (int i = 0;i < (int) g[x].size();i++){
            int y = g[x][i];
            if (y==fa) continue;
            dfs(y,x,dep+1);
        }
    
        cnt++;
        c[cnt] = -1;
        _out[x] = cnt;
    }
    
    void build(int l,int r,int rt){
        if (l==r){
            sum[rt] = c[l];
            return;
        }
        int mid = (l+r)>>1;
        build(lson);
        build(rson);
        sum[rt] = sum[rt<<1] + sum[rt<<1|1];
    }
    
    void updata(int pos,int l,int r,int rt){
        if (l==r){
            sum[rt] = 0;
            c[pos] = 0;
            return;
        }
        int mid = (l+r)>>1;
        if (pos<= mid)
            updata(pos,lson);
        else
            updata(pos,rson);
        sum[rt] = sum[rt<<1] + sum[rt<<1|1];
    }
    
    int getsum(int L,int R,int l,int r,int rt){
        if (L<=l && r <= R){
            return sum[rt];
        }
        int mid = (l+r)>>1;
        int temp1 = 0,temp2 = 0;
        if (L<=mid) temp1 = getsum(L,R,lson);
        if (mid < R) temp2 = getsum(L,R,rson);
        return temp1 + temp2;
    }
    
    char s[5];
    
    int main(){
    	#ifdef LOCAL_DEFINE
    	    freopen("rush_in.txt", "r", stdin);
    	#endif
    
        scanf("%d",&n);
        for (int i = 1;i <= n-1;i++){
            int a,b;
            scanf("%d%d",&a,&b);
            g[a].push_back(b);
            g[b].push_back(a);
        }
        dfs(1,0,1);
        build(1,cnt,1);
    
        int m;
        scanf("%d",&m);
        for (int i = 1;i <= n + m - 1;i++){
            scanf("%s",s);
            if (s[0]=='W'){
                int a;
                scanf("%d",&a);
                printf("%d
    ",getsum(1,_in[a],1,cnt,1)-1);
            }else{
                int a,b;
                scanf("%d%d",&a,&b);
                if (_dep[a]<_dep[b]) swap(a,b);
                updata(_in[a],1,cnt,1);
                updata(_out[a],1,cnt,1);
            }
        }
    	return 0;
    }
    
    
  • 相关阅读:
    Linq调试实时输出信息扩展方法(摘抄)
    RSA签名和验证数据
    Vue+abp微信扫码登录
    vue学习笔记4
    icon共享网站 可以获得wpf里用的Geometry
    wpf 父控件和子控件 各自触发鼠标按下事件
    C# Timespan Tostring 时分秒格式
    新公司第二天
    C# 反转单向链表
    经纬度转数字经纬度时,如果是负数
  • 原文地址:https://www.cnblogs.com/AWCXV/p/8577188.html
Copyright © 2011-2022 走看看