CQ_Bob @ 2024-03-12 16:53:31
这题我区间覆盖写挂了。然后把区间覆盖的代码变成了暴力单点修改,结果过了……
代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define re register
#define il inline
#define pii pair<int,int>
#define x first
#define y second
#define gc getchar()
#define rd read()
#define debug() puts("------------")
namespace yzqwq{
il int read(){
int x=0,f=1;char ch=gc;
while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=gc;}
while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+(ch^48),ch=gc;
return x*f;
}
il int qmi(int a,int b,int p){
int ans=1;
while(b){
if(b&1) ans=ans*a%p;
a=a*a%p,b>>=1;
}
return ans;
}
il auto max(auto a,auto b){return (a>b?a:b);}
il auto min(auto a,auto b){return (a<b?a:b);}
il int gcd(int a,int b){
if(!b) return a;
return gcd(b,a%b);
}
il int lcm(int a,int b){
return a/gcd(a,b)*b;
}
il void exgcd(int a,int b,int &x,int &y){
if(!b) return x=1,y=0,void(0);
exgcd(b,a%b,x,y);
int t=x;
x=y,y=t-a/b*x;
return ;
}
mt19937 rnd(time(0));
}
using namespace yzqwq;
const int N=2e5+10;
int n,m,a[N];
struct Tree{
int l,r;
int tag1,tag2;//区间覆盖,区间翻转
int lmax0,lmax1,rmax0,rmax1;
int mx0,mx1;
int cnt0,cnt1;
}tr[N<<2];
il void up(int now){
tr[now].lmax0=tr[now<<1].lmax0;
if(tr[now<<1].lmax0==(tr[now<<1].r-tr[now<<1].l+1)) tr[now].lmax0+=tr[now<<1|1].lmax0;
tr[now].lmax1=tr[now<<1].lmax1;
if(tr[now<<1].lmax1==(tr[now<<1].r-tr[now<<1].l+1)) tr[now].lmax1+=tr[now<<1|1].lmax1;
tr[now].rmax0=tr[now<<1|1].rmax0;
if(tr[now<<1|1].rmax0==(tr[now<<1|1].r-tr[now<<1|1].l+1)) tr[now].rmax0+=tr[now<<1].rmax0;
tr[now].rmax1=tr[now<<1|1].rmax1;
if(tr[now<<1|1].rmax1==(tr[now<<1|1].r-tr[now<<1|1].l+1)) tr[now].rmax1+=tr[now<<1].rmax1;
tr[now].mx0=max(tr[now<<1].mx0,tr[now<<1|1].mx0);
tr[now].mx0=max(tr[now].mx0,tr[now<<1].rmax0+tr[now<<1|1].lmax0);
tr[now].mx0=max({tr[now].mx0,tr[now].lmax0,tr[now].rmax0});
tr[now].mx1=max(tr[now<<1].mx1,tr[now<<1|1].mx1);
tr[now].mx1=max(tr[now].mx1,tr[now<<1].rmax1+tr[now<<1|1].lmax1);
tr[now].mx1=max({tr[now].mx1,tr[now].lmax1,tr[now].rmax1});
tr[now].cnt0=tr[now<<1].cnt0+tr[now<<1|1].cnt0;
tr[now].cnt1=tr[now<<1].cnt1+tr[now<<1|1].cnt1;
return ;
}
il void down(int now){
if(tr[now].tag1!=-1){//有区间覆盖
tr[now<<1].tag2=tr[now<<1|1].tag2=0;
tr[now<<1].tag1=tr[now<<1|1].tag1=tr[now].tag1;
tr[now<<1].lmax0=tr[now<<1].lmax1=tr[now<<1|1].lmax0=tr[now<<1|1].lmax1=0;
tr[now<<1].rmax0=tr[now<<1].rmax1=tr[now<<1|1].rmax0=tr[now<<1|1].rmax1=0;
tr[now<<1].mx0=tr[now<<1|1].mx0=0;
tr[now<<1].mx1=tr[now<<1|1].mx1=0;
tr[now<<1].cnt0=tr[now<<1|1].cnt0=0;
tr[now<<1].cnt1=tr[now<<1|1].cnt1=0;
if(tr[now].tag1==0){
tr[now<<1].cnt0=tr[now<<1].mx0=tr[now<<1].lmax0=tr[now<<1].rmax0=(tr[now<<1].r-tr[now<<1].l+1);
tr[now<<1|1].cnt0=tr[now<<1|1].mx0=tr[now<<1|1].lmax0=tr[now<<1|1].rmax0=(tr[now<<1|1].r-tr[now<<1|1].l+1);
}
else if(tr[now].tag1==1){
tr[now<<1].cnt1=tr[now<<1].mx1=tr[now<<1].lmax1=tr[now<<1].rmax1=(tr[now<<1].r-tr[now<<1].l+1);
tr[now<<1|1].cnt1=tr[now<<1|1].mx1=tr[now<<1|1].lmax1=tr[now<<1|1].rmax1=(tr[now<<1|1].r-tr[now<<1|1].l+1);
}
tr[now].tag1=-1;
}
if(tr[now].tag2!=0){//有区间翻转
if(tr[now<<1].tag1!=-1) tr[now<<1].tag1^=1;
if(tr[now<<1|1].tag1!=-1) tr[now<<1|1].tag1^=1;
tr[now<<1].tag2^=1,tr[now<<1|1].tag2^=1;
swap(tr[now<<1].cnt0,tr[now<<1].cnt1),
swap(tr[now<<1].lmax0,tr[now<<1].lmax1),
swap(tr[now<<1].rmax0,tr[now<<1].rmax1),
swap(tr[now<<1].mx0,tr[now<<1].mx1);
swap(tr[now<<1|1].cnt0,tr[now<<1|1].cnt1),
swap(tr[now<<1|1].lmax0,tr[now<<1|1].lmax1),
swap(tr[now<<1|1].rmax0,tr[now<<1|1].rmax1),
swap(tr[now<<1|1].mx0,tr[now<<1|1].mx1);
tr[now].tag2=0;
}
return ;
}
il void build(int now,int l,int r){
tr[now].l=l,tr[now].r=r,tr[now].tag1=-1,tr[now].tag2=0;
if(l==r){
if(a[l]==0) tr[now].cnt0=tr[now].lmax0=tr[now].rmax0=tr[now].mx0=1;
if(a[l]==1) tr[now].cnt1=tr[now].lmax1=tr[now].rmax1=tr[now].mx1=1;
return ;
}
int mid=l+r>>1;
build(now<<1,l,mid),build(now<<1|1,mid+1,r);
return up(now),void(0);
}
il void insert1(int now,int l,int r,int k){//区间覆盖
// if(tr[now].l>=l&&tr[now].r<=r){
if(tr[now].l==tr[now].r){
tr[now].cnt0=tr[now].cnt1=0;
tr[now].lmax0=tr[now].lmax1=0;
tr[now].mx0=tr[now].mx1=0;
tr[now].rmax0=tr[now].rmax1=0;
tr[now].tag2=0,tr[now].tag1=k;
if(k==0) tr[now].cnt0=tr[now].lmax0=tr[now].rmax0=tr[now].mx0=tr[now].r-tr[now].l+1;
if(k==1) tr[now].cnt1=tr[now].lmax1=tr[now].rmax1=tr[now].mx1=tr[now].r-tr[now].l+1;
return ;
}
down(now);
int mid=tr[now].l+tr[now].r>>1;
if(l<=mid) insert1(now<<1,l,r,k);
if(mid<r) insert1(now<<1|1,l,r,k);
return up(now),void(0);
}
il void insert2(int now,int l,int r){//区间翻转
if(tr[now].l>=l&&tr[now].r<=r){
swap(tr[now].cnt0,tr[now].cnt1);
swap(tr[now].lmax0,tr[now].lmax1);
swap(tr[now].mx0,tr[now].mx1);
swap(tr[now].rmax0,tr[now].rmax1);
tr[now].tag2^=1;
return ;
}
down(now);
int mid=tr[now].l+tr[now].r>>1;
if(l<=mid) insert2(now<<1,l,r);
if(mid<r) insert2(now<<1|1,l,r);
return up(now),void(0);
}
il int query1(int now,int l,int r){//区间1的数量
if(tr[now].l>=l&&tr[now].r<=r) return tr[now].cnt1;
down(now);
int ans=0,mid=tr[now].l+tr[now].r>>1;
if(l<=mid) ans+=query1(now<<1,l,r);
if(mid<r) ans+=query1(now<<1|1,l,r);
return up(now),ans;
}
il Tree query2(int now,int l,int r){//区间连续1的数量
if(tr[now].l>=l&&tr[now].r<=r) return tr[now];
down(now);
Tree ans={0,0,0,0,0,0,0,0,0,0,0,0};
int mid=tr[now].l+tr[now].r>>1;
if(l<=mid) ans=query2(now<<1,l,r);
if(mid<r){
Tree ans2=query2(now<<1|1,l,r);
ans.mx1=max(ans.mx1,ans2.mx1);
ans.mx1=max(ans.mx1,ans.rmax1+ans2.lmax1);
if(ans.lmax1==mid-max(l,tr[now].l)+1) ans.lmax1+=ans2.lmax1;
int rmax1=ans2.rmax1;
if(rmax1==min(r,tr[now].r)-(mid+1)+1) rmax1+=ans.rmax1;
ans.rmax1=rmax1;
ans.mx1=max({ans.mx1,ans.lmax1,ans.rmax1});
}
return up(now),ans;
}
il void solve(){
n=rd,m=rd;
for(re int i=1;i<=n;++i) a[i]=rd;
build(1,1,n);
for(re int i=1;i<=m;++i){
int op=rd,l=rd+1,r=rd+1;
if(op==0) insert1(1,l,r,0);
else if(op==1) insert1(1,l,r,1);
else if(op==2) insert2(1,l,r);
else if(op==3){
int ans=query1(1,l,r);
printf("%lld\n",ans);
}
else if(op==4){
Tree ans=query2(1,l,r);
printf("%lld\n",ans.mx1);
}
// for(re int j=1;j<=n;++j){
// cout<<query1(1,j,j)<<" ";
// }
// cout<<"\n";
}
return ;
}
signed main(){
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
int t=1;while(t--)
solve();
return 0;
}
/*
10 11
0 1 0 0 1 1 1 1 0 1
3 0 9
0 0 0
0 1 3
4 1 3
4 1 5
2 1 5
4 1 5
1 5 5
4 1 5
1 4 4
4 1 5
*/
第 135 行是改的暴力。