Invertible tree 线段树 + dfs 序

来源:互联网 发布:spark时间序列算法 编辑:程序博客网 时间:2024/06/02 01:53


#include <cstdio>#include <climits>#include <algorithm>#include <iostream>#include <cstring>using namespace std;int const SIZE = 100100;typedef long long weight_t;struct edge_t{    int to;    int next;}Edge[SIZE<<1];int Vertex[SIZE];int ECnt;weight_t W[SIZE];inline void mkEdge(int a,int b){    Edge[ECnt].to = b;    Edge[ECnt].next = Vertex[a];    Vertex[a] = ECnt++;    Edge[ECnt].to = a;    Edge[ECnt].next = Vertex[b];    Vertex[b] = ECnt++;}int InIdx[SIZE],OutIdx[SIZE];int InOut[SIZE<<1];int NewIdx[SIZE<<1];int NCnt;void dfs(int node,int parent){    NewIdx[NCnt] = node;    InOut[NCnt] = 1;    InIdx[node] = NCnt++;    for(int next=Vertex[node];next;next=Edge[next].next){        int son = Edge[next].to;        if ( son != parent ) dfs(son,node);    }    NewIdx[NCnt] = node;    InOut[NCnt] = -1;    OutIdx[node] = NCnt++;}int N;weight_t StSum[SIZE<<3];weight_t Lazy[SIZE<<3];int Flag[SIZE<<3];//The count of the positive number in the rangeinline int lson(int x){return x<<1;}inline int rson(int x){return lson(x)|1;}inline void _pushUp(int t){    StSum[t] = StSum[lson(t)] + StSum[rson(t)];    Flag[t] = Flag[lson(t)] + Flag[rson(t)];}inline void _pushDown(int t){    if ( 0LL == Lazy[t] ) return;    weight_t& x = Lazy[t];    int son = lson(t);    StSum[son] += Flag[son] * x;    Lazy[son] += x;    son = rson(t);    StSum[son] += Flag[son] * x;    Lazy[son] += x;    x = 0LL;}void build(int t,int s,int e){    Lazy[t] = 0LL;    if ( s == e ){        StSum[t] = InOut[s] * W[NewIdx[s]];        Flag[t] = InOut[s];        return;    }    int m = ( s + e ) >> 1;    build(lson(t),s,m);    build(rson(t),m+1,e);    _pushUp(t);}void modify(int t,int s,int e,int a,int b,weight_t delta){    if ( a <= s && e <= b ){        StSum[t] += Flag[t] * delta;        Lazy[t] += delta;        return;    }    _pushDown(t);    int m = ( s + e ) >> 1;    if ( a <= m ) modify(lson(t),s,m,a,b,delta);    if ( m < b ) modify(rson(t),m+1,e,a,b,delta);    _pushUp(t);}weight_t query(int t,int s,int e,int a,int b){    if ( a <= s && e <= b ){        return StSum[t];    }    _pushDown(t);    weight_t ret = 0LL;    int m = ( s + e ) >> 1;    if ( a <= m ) ret += query(lson(t),s,m,a,b);    if ( m < b ) ret += query(rson(t),m+1,e,a,b);    return ret;}inline weight_t query(int x){    return query(1,1,N<<1,1,InIdx[x]);}inline void modify(int x,weight_t delta){    modify(1,1,N<<1,InIdx[x],InIdx[x],delta);    modify(1,1,N<<1,OutIdx[x],OutIdx[x],delta);}inline void modifySubtree(int x,weight_t delta){    modify(1,1,N<<1,InIdx[x],OutIdx[x],delta);}inline void initTree(int n){    ECnt = NCnt = 1;    fill(Vertex,Vertex+n+1,0);}int father[100050] ;int M;bool read(){    if ( EOF == scanf("%d%d",&N,&M) ) return false;    initTree(N);    for(int i=1;i<=N;++i)  W[i] = 0 ; //scanf("%lld",W+i);    int a,b;    memset(father , 0 , sizeof(father)) ;    for(int i=1;i<N;++i){        scanf("%d%d",&a,&b);        mkEdge(a,b);        father[b] = a ;    }    dfs(1,0);    build(1,1,N<<1);    return true;}void proc(){    int cmd,x;    weight_t a;    //for(int i = 1 ; i < 10 ; i ++ ) cout << query(i) << " " ; cout << endl ;    //for(int i = 1 ; i < 10 ; i ++ ) cout << query(i) << " " ; cout << endl ;    //for(int i = 1 ; i < 10 ; i ++ ) cout << query(i) << " " ;cout << endl ;    while(M -- ){        char c[10] ;        scanf("%s",c);        if(c[0] == 'Q'){            scanf("%lld" , &a) ;            int ans = 0 ;            //cout << a << endl ;            if(a == 1) {                ans = query(a) ;            }else{                int temp = father[a] ;                ans = query(a) - query(temp) ;            }            //cout << query(a) << endl ;            if((ans & 1)) puts("B") ;            else puts("R") ;            //printf("%lld\n" , query(a) - query(temp)) ;        }else{            scanf("%d", &a);modifySubtree(a,1);        }    }}int main(){    //freopen("1.txt","r",stdin);    while( read() ) proc();    return 0;}

原创粉丝点击