1. 程式人生 > >Codeforces 877E - Danil and a Part-time Job 線段樹+dfs序

Codeforces 877E - Danil and a Part-time Job 線段樹+dfs序

esp res down its hup cout namespace 數列 update

給一個有根樹,1e5個節點,每個節點有權值0/.1,
1e5操作:
1.將一個點的子樹上所有點權值取反
2.查詢一個點的子樹的權值和 題解: 先深搜整顆樹,用dfs序建立每個點對應的區間,
等於把樹拍扁成一個數列,每次操作從就對點變成了對區間
然後就是裸線段樹
註意拍扁後的節點標號和原來的樹節點標號是不等價的,要映射一下
#include <bits/stdc++.h>
#define endl ‘\n‘
#define ll long long
#define fi first
#define se second
#define pii pair<int,int>
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define rep(ii,a,b) for(int ii=a;ii<=b;++ii)
using namespace std;
const int maxn=1e6+7;
int casn,n,m,k;
vector<int>g[maxn];
pii seg[maxn];
int vis[maxn];
int a[maxn];
int dfn;
void dfs(int now){
    seg[now].fi=++dfn;
    vis[dfn]=now;
    for(auto i:g[now]) dfs(i);
    seg[now].se=dfn;
}
class segtree{
#define nd  node[now]
#define ndl node[now<<1]
#define ndr node[now<<1|1]
    public:
    struct segnode {
        int l,r;int sum,tag;
        int mid(){return (r+l)>>1;}
        int len(){return r-l+1;}
        void update(){sum=len()-sum;tag^=1;}
    };
    vector<segnode> node;
    int cnt;
    segtree(int n) {node.resize(n<<2|3);maketree(1,n);}
    void pushup(int now){nd.sum=ndl.sum+ndr.sum;}
    void pushdown(int now){
        if(nd.tag){
            ndl.update();
            ndr.update();
            nd.tag=0;
        }
    }
    void maketree(int s,int t,int now=1){
        nd={s,t,0,0};
        if(s==t){
            nd.sum=a[vis[s]];
            return ;
        }
        maketree(s,nd.mid(),now<<1);
        maketree(nd.mid()+1,t,now<<1|1);
        pushup(now);
    }
    void update(int s,int t,int now=1){
        if(s>nd.r||t<nd.l) return ;
        if(s<=nd.l&&t>=nd.r){nd.update();return ;}
        pushdown(now);
        update(s,t,now<<1); update(s,t,now<<1|1);
        pushup(now);
    }
    int query(int s,int t,int now=1){
        if(s>nd.r||t<nd.l) return 0;
        if(s<=nd.l&&t>=nd.r) return nd.sum;
        pushdown(now);
        return query(s,t,now<<1)+query(s,t,now<<1|1);
    }
};
int main() {
    IO;
    cin>>n;
    rep(i,2,n){
        int a;cin>>a;
        g[a].push_back(i);
    }
    dfs(1);
    rep(i,1,n) cin>>a[i];
    segtree tree(n);
    cin>>m;
    string s;
    int x;
    while(m--){
        cin>>s>>x;
        if(s=="get")cout<<tree.query(seg[x].fi,seg[x].se)<<endl;
        else tree.update(seg[x].fi,seg[x].se);
    }
	return 0;
}

Codeforces 877E - Danil and a Part-time Job 線段樹+dfs序