Subtask #1过了, 但是0分
查看原帖
Subtask #1过了, 但是0分
1057425
jofish楼主2024/12/17 00:54

Subtask #1过了, 但是0分

#include <bits/stdc++.h>

using namespace std;
const int N = 1e5+3;

#define lp p<<1
#define rp p <<1|1


int n, m, arr[N];

struct node{
    int l=-1, r;
    //1的个数, 0的个数
    int sum1, sum0;
    //从左开始1和0的个数
    int seml1, seml0;
    //从右开始1和0的个数
    int semr1, semr0;
    //最长的1区间,最长的0区间
    int Mxsem1, Mxsem0;
    //标记位置
    //tag1存哪个数,tag2存是否反转
    int tag1 = -1, tag2;


    //up
    void change(int s1, int s0, int sl1, int sr1, int sl0, int sr0, int mxs1, int mxs0) {
        sum1 = s1;sum0 = s0;seml1 = sl1;seml0 = sl0;semr1 = sr1;semr0 = sr0;Mxsem1 = mxs1;Mxsem0 = mxs0;
    }

    int mid(){return l + r >>1;}

    int len() {return  r-l + 1;}
}tr[N*4];


void merge(node& x, node y) {
    x.change(
        //计数
        x.sum1+y.sum1, x.sum0+y.sum0,
        // 区间1合并
        (x.sum0 ? x.seml1 : x.sum1 +y.seml1), (y.sum0 ? y.semr1 :y.sum1 + x.semr1),
        // 区间0合并
        (x.sum1 ? x.seml0 : x.sum0 +y.seml0), (y.sum0 ? y.semr0 :y.sum0 + x.semr0),
        //更新最大区间
        max({x.Mxsem1, y.Mxsem1, x.semr1 + y.seml1}), max({y.Mxsem0, y.Mxsem0, x.semr0 +y.seml0})
    );
}

void up(int p) {
    tr[p].change(
        //计数
        tr[lp].sum1+tr[rp].sum1, tr[lp].sum0+tr[rp].sum0,
        // 区间1合并
        (tr[lp].sum0 ? tr[lp].seml1 : tr[lp].sum1 +tr[rp].seml1), (tr[rp].sum0 ? tr[rp].semr1 :tr[rp].sum1 + tr[lp].semr1),
        // 区间0合并
        (tr[lp].sum1 ? tr[lp].seml0 : tr[lp].sum0 +tr[rp].seml0), (tr[rp].sum0 ? tr[rp].semr0 :tr[rp].sum0 + tr[lp].semr0),
        //更新最大区间
        max({tr[lp].Mxsem1, tr[rp].Mxsem1, tr[lp].semr1 + tr[rp].seml1}), max({tr[rp].Mxsem0, tr[rp].Mxsem0, tr[lp].semr0 +tr[rp].seml0})
    );
}
//树上节点更新
void update(int typ, int p) {
    if (typ == 0)
        tr[p].tag2=0, tr[p].tag1=0, tr[p].change(0, tr[p].len(), 0, 0, tr[p].len(), tr[p].len(), 0, tr[p].len());
    if (typ == 1)
        tr[p].tag2=0, tr[p].tag1=1, tr[p].change(tr[p].len(), 0, tr[p].len(), tr[p].len(), 0, 0, tr[p].len(), 0);
    if (typ == 2)
        tr[p].tag2 ^= 1, swap(tr[p].sum1, tr[p].sum0), swap(tr[p].Mxsem0, tr[p].Mxsem1),
        swap(tr[p].seml1, tr[p].seml0), swap(tr[p].semr0, tr[p].semr1);

}

//标记下传
void down(int p) {
    if (tr[p].tag1 != -1) update(tr[p].tag1, lp), update(tr[p].tag1, rp);
    if (tr[p].tag2) update(2, lp), update(2, rp);
    tr[p].tag1 = -1, tr[p].tag2 = 0;
}

//构建
void build(int l = 0, int r = n-1, int p =1) {
    tr[p].l = l, tr[p].r = r;
    if (l == r ) {
        tr[p].
            change(arr[l], arr[l]^1, arr[l], arr[l], arr[l]^1, arr[l]^1, arr[l], arr[l]^1);
        return;
    }
    int mid = l + r >> 1;
    build(l, mid, lp);
    build(mid+1, r, rp);
    up(p);
}

void outtree(int p = 1) {
    if (tr[p].l == -1) return;
    outtree(lp);
    if (tr[p].l == tr[p].r) cout<<tr[p].sum1<<" ";
    outtree(rp);
}

//修改
void fix(int l, int r, int typ, int p = 1) {
    if (l <= tr[p].l &&tr[p].r <= r) {
        update(typ, p);
        return;
    }
    down(p);
    if (l <= tr[p].mid()) fix(l, r, typ, lp);
    if (r > tr[p].mid()) fix(l, r, typ, rp);
    up(p);
}

node query(int l, int r, int p =1) {
    if (l <= tr[p].l && tr[p].r <= r) return tr[p];
    down(p);
    node sum = node();
    if (l <= tr[p].mid()) sum = query(l, r, lp);
    if (r > tr[p].mid())  merge(sum, query(l, r ,rp));
    return sum;
}


int op, l, r;

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    cin>>n>>m;
    for (int i=0; i<n; i++) cin>>arr[i];
    build();
    while(m--) {
        cin>>op>>l>>r;
        if (op < 3)
            fix(l, r, op);
        else {
                node ans = query(l, r); cout<<(op==3 ? ans.sum1 : ans.Mxsem1)<<"\n";
        }
    }

}

2024/12/17 00:54
加载中...