CF707D Persistent Bookcase(主席树+bitset)

这道题看到操作4就能想到使用可持久化数据结构

对于这一题的初始想法,是把二维映射到一维,前两个操作是单点修改,第三个是区间01反转

感觉应该是可做的,但是不太好写。

一种好写的做法是,维护行,对于每行维护一个bitset,这样三种操作就都很容易做了

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
const int N=2e5+10;
const int mod=998244353;
struct node{
    int l,r;
    int sum;
    bitset<1010> bt;
}tr[N*10];
int n,m;
int rt[N],idx;
bitset<1010> bs;
void build(int &u,int l,int r){
    u=++idx;
    if(l==r){
        return ;
    }
    else{
        int mid=l+r>>1;
        build(tr[u].l,l,mid);
        build(tr[u].r,mid+1,r);
    }
}
void modify(int &p,int q,int l,int r,int opt,int x,int y){
    p=++idx;
    tr[p]=tr[q];
    if(l==r){
        if(opt==1){
            tr[p].bt.set(y);
        }
        else if(opt==2){
            tr[p].bt.reset(y);
        }
        else{
            tr[p].bt^=bs;
        }
        tr[p].sum=tr[p].bt.count();
        return ;
    }
    int mid=l+r>>1;
    if(x<=mid)
        modify(tr[p].l,tr[q].l,l,mid,opt,x,y);
    else
        modify(tr[p].r,tr[q].r,mid+1,r,opt,x,y);
    tr[p].sum=tr[tr[p].l].sum+tr[tr[p].r].sum;
}
int main(){
    ios::sync_with_stdio(false);
    int q;
    cin>>n>>m>>q;
    int i;
    build(rt[0],1,n);
    for(i=1;i<=m;i++){
        bs.set(i);
    }
    for(i=1;i<=q;i++){
        int opt;
        cin>>opt;
        int l,r;
        if(opt==1){
            cin>>l>>r;
            modify(rt[i],rt[i-1],1,n,1,l,r);
        }
        else if(opt==2){
            cin>>l>>r;
            modify(rt[i],rt[i-1],1,n,2,l,r);
        }
        else if(opt==3){
            cin>>l;
            modify(rt[i],rt[i-1],1,n,3,l,0);
        }
        else{
            int k;
            cin>>k;
            rt[i]=rt[k];
        }
        cout<<tr[rt[i]].sum<<endl;
    }
    return 0;
}
View Code
没有人不辛苦,只有人不喊疼
原文地址:https://www.cnblogs.com/ctyakwf/p/14605141.html