CF877E

解题思路 DFS序 + 线段树

当看到这个题的时候,发现是一个树上问题且存在修改和询问,这个题有俩种操作

  • 区间翻转
  • 区间查询1的个数

很显然了线段树可以轻松维护这种信息,sum 记录区间1的个数,lzy懒标记。
由于查询的是树上问题 可以用DFS序从树上问题转换成线性问题,然后就可以线段树暴力硬屮了

具体细节看代码了

#include<bits/stdc++.h>
using namespace std;
// #define int long long
#define endl "\n"
#define x first
#define y second
typedef pair<int,int> pii;
typedef long long ll;
typedef unsigned long long ull;
const int N=1000010,M=1010,mod=998244353;
int a[N],m;
struct node{
    int l,r,sum,lzy;
}tr[N];
int n,L[N],R[N],t,pos[N];
vector<int> e[N];
void dfs(int u)
{
    L[u]=++t;
    pos[t]=u;
    for(auto j:e[u])
        dfs(j);
    R[u]=t;
}
void pushdown(int u)
{
    int x=tr[u].lzy;
    if(!x) return ;
    tr[u<<1].lzy^=1;
    tr[u<<1].sum=(tr[u<<1].r-tr[u<<1].l+1)-tr[u<<1].sum;
    tr[u<<1|1].lzy^=1;
    tr[u<<1|1].sum=(tr[u<<1|1].r-tr[u<<1|1].l+1)-tr[u<<1|1].sum;
    tr[u].lzy=0;
}
void pushup(int u)
{
    tr[u].sum=tr[u<<1].sum+tr[u<<1|1].sum;
}
void build(int u,int l,int r)
{
    if(l==r)
    {
        int x=pos[l];
        tr[u]={l,r,a[x],0};
        return ;
    }
    tr[u]={l,r};
    int mid=l+r>>1;
    build(u<<1,l,mid),build(u<<1|1,mid+1,r);
    pushup(u);
}
void modify(int u,int l,int r)
{
    if(tr[u].l>r||tr[u].r<l) return ;
    if(tr[u].l>=l&&tr[u].r<=r)
    {
        tr[u].lzy^=1;
        tr[u].sum=(tr[u].r-tr[u].l+1)-tr[u].sum;
        return ;
    }
    pushdown(u);
    int mid=tr[u].l+tr[u].r>>1;
    if(mid>=l) modify(u<<1,l,r);
    if(r>mid) modify(u<<1|1,l,r);
    pushup(u);
}
int query(int u,int l,int r)
{
    if(tr[u].l>r||tr[u].r<l) return 0;
    if(tr[u].l>=l&&tr[u].r<=r) return tr[u].sum;
    pushdown(u);
    int mid=tr[u].l+tr[u].r>>1;
    int ans=0;
    if(mid>=l) ans+=query(u<<1,l,r);
    if(r>mid) ans+=query(u<<1|1,l,r);
    return ans;
}
void solve()
{
    cin >> n;
    for(int i=2;i<=n;i++)
    {
        int x;
        cin >> x;
        e[x].push_back(i);
    }
    dfs(1);
    for(int i=1;i<=n;i++) cin >> a[i];
    build(1,1,n);
    cin >> m;
    while(m--)
    {
        string op;
        int v;
        cin >> op >> v;
        if(op=="get") cout << query(1,L[v],R[v]) << endl;
        else modify(1,L[v],R[v]);
    }
}

int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int T=1;
	while(T--) solve();
	return 0;
}

题目链接https://codeforces.com/problemset/problem/877/E

posted @ 2024-04-19 18:11  sty_stability  阅读(39)  评论(0)    收藏  举报