【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\n",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;
}

posted @ 2018-03-15 23:32  AWCXV  阅读(141)  评论(0编辑  收藏  举报