社区讨论
超级无敌难改的代码
学术版参与者 1已保存回复 0
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @lw28kiks
- 此快照首次捕获于
- 2024/05/11 23:03 2 年前
- 此快照最后确认于
- 2024/05/11 23:35 2 年前
对此,我无话可说
请大佬kankan
CPP请大佬kankan
#include<bits/stdc++.h>
using namespace std;
const int N = 100007;
int n,m;
int mx[N*4][3],lmx[N*4][3],rmx[N*4][3];
int lz[N*4],sum[N*4],con[N*4];
void pushdown(int k,int l,int r,int mid){
if(lz[k]!=-1){
int v;
lz[k*2]=lz[k*2+1]=lz[k];
v=lz[k];
sum[k*2]=v*(mid-l+1);
sum[k*2+1]=v*(r-mid);
mx[k*2][v]=lmx[k*2][v]=rmx[k*2][v]=mid-l+1;
mx[k*2][v^1]=lmx[k*2][v^1]=rmx[k*2][v^1]=0;
mx[k*2+1][v]=lmx[k*2+1][v]=rmx[k*2+1][v]=r-mid;
mx[k*2+1][v^1]=lmx[k*2+1][v^1]=rmx[k*2+1][v^1]=0;
lz[k]=-1;
con[k]=con[k*2]=con[k*2+1]=0;
return ;
}
if(con[k]){
con[k*2]^=1;
con[k*2+1]^=1;
if(lz[k*2]!=-1) lz[k*2]^=1;
if(lz[k*2+1]!=-1) lz[k*2+1]^=1;
sum[k*2]=mid-l+1-sum[k*2];
sum[k*2+1]=r-mid-sum[k*2+1];
swap(mx[k*2][0],mx[k*2][1]);
swap(lmx[k*2][0],lmx[k*2][1]);
swap(rmx[k*2][0],rmx[k*2][1]);
swap(mx[k*2+1][0],mx[k*2+1][1]);
swap(lmx[k*2+1][0],lmx[k*2+1][1]);
swap(rmx[k*2+1][0],rmx[k*2+1][1]);
con[k]=0;
return ;
}
return ;
}
void pushup(int k,int l,int r,int mid){
sum[k]=sum[k*2]+sum[k*2+1];
for(int i=0;i<2;i++){
lmx[k][i]=lmx[k*2][i];
rmx[k][i]=rmx[k*2+1][i];
if(sum[k*2] == i * (mid - l + 1)){
lmx[k][i] += lmx[k*2+1][i];
}
if(sum[k*2+1] == i * (r - mid)){
rmx[k][i] += rmx[k*2][i];
}
mx[k][i]=lmx[k*2+1][i]+rmx[k*2][i];
mx[k][i] = max(mx[k][i], mx[k<<1][i]);
mx[k][i] = max(mx[k][i], mx[k<<1|1][i]);
}
}
void pushup_shi(int rt, int l, int r,int mid)
{
sum[rt] = sum[rt<<1] + sum[rt<<1|1];
for(int i = 0; i < 2; ++i){
lmx[rt][i] = lmx[rt<<1][i];
if(sum[rt<<1] == i * (mid - l + 1)){
lmx[rt][i] += lmx[rt<<1|1][i];
}
rmx[rt][i] = rmx[rt<<1|1][i];
if(sum[rt<<1|1] == i * (r - mid)){
rmx[rt][i] += rmx[rt<<1][i];
}
mx[rt][i] = rmx[rt<<1][i] + lmx[rt<<1|1][i];
mx[rt][i] = max(mx[rt][i], mx[rt<<1][i]);
mx[rt][i] = max(mx[rt][i], mx[rt<<1|1][i]);
}
return;
}
void build(int k,int l,int r){
lz[k]=-1;
con[k]=0;
if(l==r){
int v;
scanf("%d",&v);
sum[k]=v;
mx[k][v]=1;
lmx[k][v]=1;
rmx[k][v]=1;
return ;
}
int mid=(l+r)/2;
build(k*2,l,mid);
build(k*2+1,mid+1,r);
pushup(k,l,r,mid);
}
void modify(int k,int l,int r,int x,int y,int opt){
if(x<=l and r<=y){
if(opt<=1){
lz[k]=opt;
con[k]=0;
sum[k]=opt*(r-l+1);
mx[k][opt]=lmx[k][opt]=rmx[k][opt]=r-l+1;
mx[k][opt^1]=lmx[k][opt^1]=rmx[k][opt^1]=0;
return ;
}else{
con[k]^=1;
if(lz[k]!=-1) lz[k]^=1;
sum[k]=r-l+1-sum[k];
swap(mx[k][0],mx[k][1]);
swap(lmx[k][0],lmx[k][1]);
swap(rmx[k][0],rmx[k][1]);
return ;
}
}
int mid=(l+r)/2;
pushdown(k,l,r,mid);
if(x<=mid) modify(k*2,l,mid,x,y,opt);
if(mid<y) modify(k*2+1,mid+1,r,x,y,opt);
pushup(k,l,r,mid);
return ;
}
int query(int k,int l,int r,int x,int y,int opt){
if(x<=l and r<=y){
if(opt==3) return sum[k];
else return mx[k][1];
}
int mid=(l+r)/2,ans=0;
pushdown(k,l,r,mid);
if(x<=mid){
if(opt==3){
ans+=query(k*2,l,mid,x,y,opt);
}else{
ans=max(ans,query(k*2,l,mid,x,y,opt));
}
}
if(mid<y){
if(opt==3){
ans+=query(k*2+1,mid+1,r,x,y,opt);
}else{
ans=max(ans,query(k*2+1,mid+1,r,x,y,opt));
}
}
if(opt == 4 && x <= mid && mid < y){
int tl = min(mid - x + 1, rmx[k*2][1]);
int tr = min(y - mid, lmx[k*2+1][1]);
ans = max(ans, tl + tr);
}
pushup(k,l,r,mid);
return ans;
}
int main(){
scanf("%d%d",&n,&m);
build(1,0,n-1);
while(m--){
int opt,l,r;
cin>>opt>>l>>r;
if(opt<3) modify(1,0,n-1,l,r,opt);
else printf("%d\n",query(1,0,n-1,l,r,opt));
}
return 0;
}
/*
lazy标记该区间是否整个被赋值
con标记该区间是否被反转
sum标记该区间1的个数
mx0/1标记该区间最多的连续0/1个数
lmx0/1标记该区间从左端点开始最多的连续的0/1个数
rmx0/1标记该区间从右端点开始最多的连续的0/1个数
*/
回复
共 0 条回复,欢迎继续交流。
正在加载回复...