求调,悬赏关注

P2572 [SCOI2010] 序列操作

Anonymely @ 2022-07-29 08:07:02

#include<bits/stdc++.h>
using namespace std;

#define newline putchar('\n')
#define newspace putchar(' ')
#define ll long long
#define inf 1000000005
#define mod 998244353
#define eps 0.0000001
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
#define N 500005

namespace fastIO {
    template<class T> void read(T &x) {
        x=0;
        int fl=1;
        char ch=getchar();
        while(ch<'0'||ch>'9') {
            if(ch=='-')fl=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9') {
            x=(x<<1)+(x<<3)+(ch&15);
            ch=getchar();
        }
        x*=fl;
    }
    template<class T> void read(T &x,T &y) {
        read(x);
        read(y);
    }
    template<class T> void read(T &x,T &y,T &z) {
        read(x);
        read(y);
        read(z);
    }
    template<class T> void write(T x) {
        if(x<0) {
            putchar('-');
            x=-x;
        }
        if(x/10)write(x/10);
        putchar(x%10+'0');
    }
    template<class T> void read(T *a,T n) {
        for(int i=1; i<=n; i++)read(a[i]);
    }
    template<class T> void write(T *a,T n) {
        for(int i=1; i<=n; i++)write(a[i]),newspace;
    }
}

using namespace fastIO;

namespace math {
    template<class T> ll fastpow(T a,T b,T md=1e18) {
        ll ans=1;
        for(; b; b>>=a,a=(a*a)%mod)if(b&1)ans=ans*a%md;
        return ans;
    }
    template<class T> ll A(T n,T m,T md=1e18) {
        ll ans1=1,ans2=1;
        for(int i=1; i<=n-m; i++)ans1=ans1*i%md,ans2=ans2*i%md;
        for(int i=n-m=1; i<=n; i++)ans1=ans1*i%md;
        return ans1*fastpow(ans2,md-2,md)%md;
    }
    template<class T> ll C(int n,int m,T md=1e18) {
        return A(n,m,md)*fastpow(A(m,m,md),md-2,md)%md;
    }
    template<class T> ll myfloor(T n,T m) {
        return n%m==0 ? n/m : (n/m+1);
    }
}

using namespace math;

int n,m;
struct tree {
    int l,r;
    int sum;
    int tag;//翻转 
    int res;
    int lval[2],rval[2];
    int val[2];
    //int len;
} t[N<<2];
int a[N];

int lson(int p) {
    return p<<1;
}
int rson(int p) {
    return (p<<1)|1;
}
int md(int l,int r) {
    return (l+r)>>1;
}
#define lp (p<<1)
#define rp ((p<<1)|1)

void pushup(int p) {
    t[p].sum = t[lp].sum + t[rp].sum;
    for (int i = 0; i < 2; i ++) {
        t[p].lval[i] = t[lp].lval[i];
        if (t[lp].lval[i] == t[lp].r - t[lp].l + 1) t[p].lval[i] += t[rp].lval[i];
        //if (i==0 && t[lp].)
        t[p].rval[i] = t[rp].rval[i];
        if (t[rp].lval[i] == t[rp].r - t[rp].l + 1) t[p].rval[i] += t[lp].rval[i];
        t[p].val[i] = max(t[lp].val[i], t[rp].val[i]);
        t[p].val[i] = max(t[p].val[i], t[lp].rval[i] + t[rp].lval[i]);
    }
}

void change(int p) {
    swap(t[p].lval[0], t[p].lval[1]);
    swap(t[p].rval[0], t[p].rval[1]);
    swap(t[p].val[0], t[p].val[1]);
}

void get(int p,int v) {
    t[p].sum = (t[p].r - t[p].l + 1) * v;
    t[p].lval[v] = t[p].rval[v] = t[p].val[v] = t[p].r - t[p].l + 1;
    t[p].lval[v^1] = t[p].rval[v^1] = t[p].val[v^1] = 0;
}

void pushdown(int p) {
    if (t[p].res != -1) {
        int v = t[p].res;
        t[p].tag = 0;
        t[lp].res = t[rp].res = v;
        t[lp].sum = (t[lp].r - t[lp].l + 1) * v;
        t[rp].sum = (t[rp].r - t[rp].l + 1) * v;
        t[lp].tag = t[rp].tag = 0;
        t[lp].lval[v] = t[lp].rval[v] = t[lp].val[v] = t[lp].r - t[lp].l + 1;
        t[rp].lval[v] = t[rp].rval[v] = t[rp].val[v] = t[rp].r - t[rp].l + 1;
        t[lp].lval[v^1] = t[lp].rval[v^1] = t[lp].val[v^1] = 0;
        t[rp].lval[v^1] = t[rp].rval[v^1] = t[rp].val[v^1] = 0;
        t[p].res = -1;
    }
    if (t[p].tag) {
        t[lp].sum = (t[lp].r - t[lp].l + 1) - t[lp].sum;
        t[rp].sum = (t[rp].r - t[rp].l + 1) - t[rp].sum;
        if (t[lp].res != -1) t[lp].res ^= 1;
        else t[lp].tag ^= 1;
        if (t[rp].res != -1) t[rp].res ^= 1;
        else t[rp].tag ^= 1;
        change(lp);
        change(rp);
        t[p].tag=0; 
    }
}

void build(int p,int l,int r) {
    t[p].l = l,t[p].r = r;
    t[p].res = -1;
    if (l == r) {
        t[p].sum = a[l];
        t[p].lval[a[l]] = 1,t[p].rval[a[l]] = 1,t[p].val[a[l]] = 1;
        return ;
    }
    int mid=md(l,r);
    build(lp, l, mid);
    build(rp, mid+1, r);
    pushup(p);
}

void update(int p,int l,int r,int op) {
    pushdown(p);
    if (l <= t[p].l && t[p].r <= r) {
        if (op == 0 || op == 1) {
            t[p].res=op;
            get(p, op);
        } else {
            t[p].sum = (t[p].r - t[p].l + 1) - t[p].sum;
            t[p].tag ^= 1;
            change(p); 
        }
        return ;
    }
    int mid = md(t[p].l , t[p].r);
    if (l<=mid) update(lp, l, r, op);
    if (mid<r) update(rp, l, r, op);
    pushup(p);
}

int query_sum(int p,int l,int r) {
    if (l <= t[p].l && t[p].r <= r) return t[p].sum;
    pushdown(p);
    int ans = 0;
    int mid = md(t[p].l, t[p].r);
    if (l<=mid) ans += query_sum(lp, l, r);
    if (mid<r) ans += query_sum(rp, l, r);
    return ans;
}

int query_max(int p,int l,int r) {
    if (l <= t[p].l && t[p].r <= r) return t[p].val[1];
    pushdown(p);
    int ans = 0;
    int mid = md(t[p].l, t[p].r);
    if (l<=mid) ans = max(ans, query_max(lp, l, r));
    if (mid<r) ans = max(ans, query_max(rp, l, r));
    return ans;
}

signed main() {
    read(n, m);
    for (int i = 1; i <= n; i ++) read(a[i]);
    build(1, 1, n);
    while (m--) {
        int op,l,r;
        l++,r++;
        read(op, l, r);
        if (op <= 2) update(1, l, r, op);
        else if (op == 3) write(query_sum(1, l, r)),newline;
        else write(query_max(1, l, r)),newline;
    }
    return 0;
}

by qinyubo @ 2022-07-29 09:02:19

@trisomy

       int op,l,r;
       l++,r++;
       read(op, l, r);

我这种菜鸡丝毫看不懂先++再输入是有什么奥妙/doge


by qinyubo @ 2022-07-29 09:49:14

@trisomy 而且你在 query_max 时不能直接取 max,而应当用类似节点合并的方式,否则会假掉。

Hack:

input
4 1
1 1 1 1
4 1 3
output
3
your output
2

这是因为你 query_max 时返回的是 max(t[2, 2].val[1], t[3, 4].val[1]),也就是 2(用区间表示的节点)


by Anonymely @ 2022-07-29 12:01:02

@qinyubo 感谢,已过


|