好像push和修改的地方错了,望高人指点迷津

P2572 [SCOI2010] 序列操作

管泽昊1691 @ 2021-10-05 10:45:29

#include <bits/stdc++.h>

using namespace std;
const int N = 1e6 + 1;

int n,m;
bool opsi[N];
int co[N];
int tree[N];
int a[N];
int tag[N];

int Max;

inline int ls(int wei){
    return wei << 1;
}

inline int rs(int wei){
    return wei << 1 | 1;
}

void build(int l,int r,int wei){
    opsi[wei] = false;
    co[wei] = -1;
    if(l >= r){
        tree[wei] = a[l];
        return;
    }

    int mid = (r + l) >> 1;
    build(l,mid,ls(wei));
    build(mid + 1,r,rs(wei));
    tree[wei] = tree[ls(wei)] + tree[rs(wei)];

}

inline void f(int wei,int l,int r,int k,bool fan){
    if(k != -1) tree[wei] = (r - l + 1) * k;
    if(fan) tree[wei] = (r - l + 1) - tree[wei];

    co[wei] = k;
    opsi[wei] = fan;
}

void push_down(int wei,int l,int r){
    int mid = (r + l) >> 1;
    f(ls(wei),l,mid,co[wei],opsi[wei]);
    f(rs(wei),mid + 1,r,co[wei],opsi[wei]);
    opsi[wei] = false;
    co[wei] = -1;
}

void cover(int nl,int nr,int l,int r,int wei,int k){
    if(nl <= l && nr >= r){
        tree[wei] = (r - l + 1) * k;
        co[wei] = k;
        opsi[wei] = false;
        return;
    }

    push_down(wei,l,r);
    int mid = (r + l) >> 1;
    if(nl <= mid) cover(nl,nr,l,mid,ls(wei),k);
    if(nr > mid) cover(nl,nr,mid + 1,r,rs(wei),k);
    tree[wei] = tree[ls(wei)] + tree[rs(wei)];
}

void opp(int nl,int nr,int l,int r,int wei){
    if(nl <= l && nr >= r){
        tree[wei] = (r - l + 1) - tree[wei];
        opsi[wei] = true;
        return; 
    }

    push_down(wei,l,r);
    int mid = (r + l) >> 1;
    if(nl <= mid) opp(nl,nr,l,mid,ls(wei));
    if(nr > mid) opp(nl,nr,mid + 1,r,rs(wei));
    tree[wei] = tree[ls(wei)] + tree[rs(wei)];
}

int query(int nl,int nr,int l,int r,int wei){
    int res = 0;
    if(nl <= l && nr >= r){
        return tree[wei];
    }

    push_down(wei,l,r);
    int mid = (r + l) / 2;
    if(nl <= mid) res += query(nl,nr,l,mid,ls(wei));
    if(nr > mid) res += query(nl,nr,mid + 1,r,rs(wei));
    return res; 
}

int colim(int nl,int nr,int l,int r,int wei){
    int res = 0;
    if(nl <= l && nr >= r && tree[wei] == (r - l + 1)){
        Max = max(tree[wei],Max);
        return tree[wei];
    }
    if(tree[wei] <= Max) return 0;

    push_down(wei,l,r);
    int mid = (r + l) / 2;
    if(nl <= mid) res = max(res,colim(nl,nr,l,mid,ls(wei)));
    if(nr > mid) res = max(res,colim(nl,nr,mid + 1,r,rs(wei)));
    return res; 
}

int main(){
    scanf("%d%d",&n,&m);
    for(int i = 1;i <= n;i ++){
        scanf("%d",&a[i]);
    }

    build(1,n,1);

    for(int i = 1;i <= m;i ++){
        int a,l,r;
        scanf("%d%d%d",&a,&l,&r);
        l++,r++;
        if(a == 0) cover(l,r,1,n,1,0);
        if(a == 1) cover(l,r,1,n,1,1);
        if(a == 2) opp(l,r,1,n,1);
        if(a == 3) printf("%d\n",query(l,r,1,n,1));             

        if(a == 4) {
            Max = 0;
            printf("%d\n",colim(l,r,1,n,1));
        }
    }
}

by 二中_张士豪 @ 2021-10-05 10:59:48

#include <bits/stdc++.h>

using namespace std;
const int N = 1e6 + 1;

int n,m;
bool opsi[N];
int co[N];
int tree[N];
int a[N];
int tag[N];

int Max;

inline int ls(int wei){
    return wei << 1;
}

inline int rs(int wei){
    return wei << 1 | 1;
}

void build(int l,int r,int wei){
    opsi[wei] = false;
    co[wei] = -1;
    if(l >= r){
        tree[wei] = a[l];
        return;
    }

    int mid = (r + l) >> 1;
    build(l,mid,ls(wei));
    build(mid + 1,r,rs(wei));
    tree[wei] = tree[ls(wei)] + tree[rs(wei)];

}

inline void f(int wei,int l,int r,int k,bool fan){
    if(k != -1) tree[wei] = (r - l + 1) * k;
    if(fan) tree[wei] = (r - l + 1) - tree[wei];

    co[wei] = k;
    opsi[wei] = fan;
}

void push_down(int wei,int l,int r){
    int mid = (r + l) >> 1;
    f(ls(wei),l,mid,co[wei],opsi[wei]);
    f(rs(wei),mid + 1,r,co[wei],opsi[wei]);
    opsi[wei] = false;
    co[wei] = -1;
}

void cover(int nl,int nr,int l,int r,int wei,int k){
    if(nl <= l && nr >= r){
        tree[wei] = (r - l + 1) * k;
        co[wei] = k;
        opsi[wei] = false;
        return;
    }

    push_down(wei,l,r);
    int mid = (r + l) >> 1;
    if(nl <= mid) cover(nl,nr,l,mid,ls(wei),k);
    if(nr > mid) cover(nl,nr,mid + 1,r,rs(wei),k);
    tree[wei] = tree[ls(wei)] + tree[rs(wei)];
}

void opp(int nl,int nr,int l,int r,int wei){
    if(nl <= l && nr >= r){
        tree[wei] = (r - l + 1) - tree[wei];
        opsi[wei] = true;
        return; 
    }

    push_down(wei,l,r);
    int mid = (r + l) >> 1;
    if(nl <= mid) opp(nl,nr,l,mid,ls(wei));
    if(nr > mid) opp(nl,nr,mid + 1,r,rs(wei));
    tree[wei] = tree[ls(wei)] + tree[rs(wei)];
}

int query(int nl,int nr,int l,int r,int wei){
    int res = 0;
    if(nl <= l && nr >= r){
        return tree[wei];
    }

    push_down(wei,l,r);
    int mid = (r + l) / 2;
    if(nl <= mid) res += query(nl,nr,l,mid,ls(wei));
    if(nr > mid) res += query(nl,nr,mid + 1,r,rs(wei));
    return res; 
}

int colim(int nl,int nr,int l,int r,int wei){
    int res = 0;
    if(nl <= l && nr >= r && tree[wei] == (r - l + 1)){
        Max = max(tree[wei],Max);
        return tree[wei];
    }
    if(tree[wei] <= Max) return 0;

    push_down(wei,l,r);
    int mid = (r + l) / 2;
    if(nl <= mid) res = max(res,colim(nl,nr,l,mid,ls(wei)));
    if(nr > mid) res = max(res,colim(nl,nr,mid + 1,r,rs(wei)));
    return res; 
}

int main(){
    scanf("%d%d",&n,&m);
    for(int i = 1;i <= n;i ++){
        scanf("%d",&a[i]);
    }

    build(1,n,1);

    for(int i = 1;i <= m;i ++){
        int a,l,r;
        scanf("%d%d%d",&a,&l,&r);
        l++,r++;
        if(a == 0) cover(l,r,1,n,1,0);
        if(a == 1) cover(l,r,1,n,1,1);
        if(a == 2) opp(l,r,1,n,1);
        if(a == 3) printf("%d\n",query(l,r,1,n,1));             

        if(a == 4) {
            printf("%d\n",colim(l,r,1,n,1));
        }
    }
}

by 二中_张士豪 @ 2021-10-05 11:00:21

这样就行了


|