求调,只过了一个hack点和样例,或者小数据hack
查看原帖
求调,只过了一个hack点和样例,或者小数据hack
1019606
KouMoSir楼主2024/4/5 15:54
#include<algorithm>
#include<iostream>
#include<iomanip>
#include<utility>
#include<string>
#include<queue>
#include<cmath>
#include<stack>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> pa;
const ll N = 1e5 + 10, MOD = 1e9 + 7, INF = 0x7fffffffffffffff;
const ll M = 1e9 + 7, MM = 1e9 + 9, B = 233;
ll t, n, q;
class cmp {
public:
    bool operator() (const pa& x, const pa& y)const {
        if (x.second != y.second)return x.second > y.second;
        else return x.first < y.first;
    }
};
ll con[4 * N][8];
// con保存信息
// 0246保存0相关的数据,1357保存1相关的数据
ll tag[4 * N], a[N];
void push_up(int l,int r,int ind) {
    //0 0 0的个数
    //1 1 1的个数
    //2 000 前缀连续0
    //3 111 前缀连续1
    //4 xxx000 后缀连续0
    //5 xxx111 后缀连续1
    //6 000000 区间内最长连续0
    //7 111111 区间内最长连续1
    ll mid = (l + r) / 2;
    for (int i = 0; i <= 1; i++)con[ind][i] = con[ind * 2][i] + con[ind * 2 + 1][i];
    for (int i = 2; i <= 3; i++) {
        con[ind][i] = con[ind * 2][i];
        if (con[ind][i] == mid - l + 1)con[ind][i] += con[ind * 2 + 1][i];
        //特判,如果前半区间的前缀为前半区间长度,那么就可以延申到后半区间的前缀
    }
    for (int i = 4; i <= 5; i++) {
        con[ind][i] = con[ind * 2 + 1][i];
        if (con[ind][i] == r - mid)con[ind][i] += con[ind * 2][i];
        //特判,如果后半区间的后缀为后半区间长度,那么就可以延申到前半区间的后缀
    }
    con[ind][6] = max({ con[ind * 2][6],con[ind * 2 + 1][6],con[ind][2],con[ind][4],con[ind * 2][4] + con[ind * 2 + 1][2] });// 最长连续0
    con[ind][7] = max({ con[ind * 2][7],con[ind * 2 + 1][7],con[ind][3],con[ind][5],con[ind * 2][5] + con[ind * 2 + 1][3] });// 最长连续1
}
void build(int l, int r, int ind) {
    if (l == r) {
        for (int i = 0; i < 8; i++)con[ind][i] = 0;
        if (a[l] == 1)for (int i = 1; i <= 7; i += 2)con[ind][i] = 1;
        else for (int i = 0; i <= 7; i += 2)con[ind][i] = 1;
        return;
    }
    ll mid = (l + r) / 2;
    build(l, mid, ind * 2);
    build(mid + 1, r, ind * 2 + 1);
    push_up(l, r, ind);
}
void f(int l, int r, int ind,int ty) {
    if (ty == 1) {
        //交换
        for (int i = 0; i <= 7; i += 2) swap(con[ind][i], con[ind][i + 1]);
    }
    else if (ty == 2) {
        //全部更新为0
        for (int i = 0; i <= 7; i += 2)con[ind][i] = r - l + 1;
        for (int i = 1; i <= 7; i += 2)con[ind][i] = 0;
    }
    else if (ty == 3) {
        //全部更新为1
        for (int i = 1; i <= 7; i += 2)con[ind][i] = r - l + 1;
        for (int i = 0; i <= 7; i += 2)con[ind][i] = 0;
    }
    tag[ind] = ty;
}
void push_down(int l, int r, int ind) {
    if (tag[ind] == 0)return;
    ll mid = (l + r) / 2;
    f(l, mid, ind * 2, tag[ind]);
    f(mid + 1, r, ind * 2 + 1, tag[ind]);
    tag[ind] = 0;
}
void udp(int l, int r, int ind, int tmpl, int tmpr, int ty) {
    if (l >= tmpl && r <= tmpr) {
        f(l, r, ind, ty);//f是对con保存信息的修改函数
        return;
    }
    push_down(l, r, ind);
    ll mid = (l + r) / 2;
    if (mid >= tmpl)udp(l, mid, ind * 2, tmpl, tmpr, ty);
    if (mid + 1 <= tmpr)udp(mid + 1, r, ind * 2 + 1, tmpl, tmpr, ty);
    push_up(l, r, ind);
}
ll query(int l, int r, int ind, int tmpl, int tmpr, int num) {
    if (l >= tmpl && r <= tmpr) {
        return con[ind][num];
    }
    push_down(l, r, ind);
    ll resl = 0, resr = 0, res = 0;
    ll mid = (l + r) / 2;
    if (mid >= tmpl)resl = query(l, mid, ind * 2, tmpl, tmpr, num);
    if (mid + 1 <= tmpr)resr = query(mid + 1, r, ind * 2 + 1, tmpl, tmpr, num);
    push_up(l, r, ind);
    if (num == 1)return resl + resr;
    else if (num == 7) {
        res = max(resl, resr);//前后区间合并时,先看两段区间的最长连续
        resl = min(mid - tmpl + 1, con[ind * 2][5]);
        resr = min(tmpr - mid, con[ind * 2 + 1][3]);
        res = max(res, resl + resr);//再看前区间的后缀连接上后区间的前缀 的总长度
        return res;
    }
}
void solve() {
    cin >> n >> q;
    for (int i = 1; i <= n; i++)cin >> a[i];
    build(1, n, 1);
    ll op, l, r;
    while (q--) {
        cin >> op >> l >> r;
        l++, r++;
        if (op == 0) {
            udp(1, n, 1, l, r, 2);
        }
        else if (op == 1) {
            udp(1, n, 1, l, r, 3);
        }
        else if (op == 2) {
            udp(1, n, 1, l, r, 1);
        }
        else if (op == 3) {
            cout << query(1, n, 1, l, r, 1) << '\n';
        }
        else if (op == 4) {
            cout << query(1, n, 1, l, r, 7) << '\n';
        }
    }
}

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

*/
2024/4/5 15:54
加载中...