社区讨论
只有sub#1过了,求条QWQ
P2572[SCOI2010] 序列操作参与者 2已保存回复 4
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 4 条
- 当前快照
- 1 份
- 快照标识符
- @mhjl9bnp
- 此快照首次捕获于
- 2025/11/04 04:24 4 个月前
- 此快照最后确认于
- 2025/11/04 04:24 4 个月前
救救我QWQ
CPP#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdio>
using namespace std;
const int N=1e6+7;
int n,m,a[N],ans,pre;
struct node
{
int l,r,val;
int sum,maxx;
int maxl,maxr;
int Imaxx,Imaxl,Imaxr;
}t[4*N];
void pushup(int id)
{
t[id].sum=t[id*2].sum+t[id*2+1].sum;
t[id].maxl=t[id*2].maxl;
t[id].Imaxl=t[id*2+1].Imaxl;
if(t[id].maxl==t[id*2].r-t[id*2].l+1)
{
t[id].maxl+=t[id*2+1].maxl;
}
if(t[id].Imaxl==t[id*2].r-t[id*2].l+1)
{
t[id].Imaxl+=t[id*2+1].Imaxl;
}
t[id].Imaxr=t[id*2+1].Imaxr;
t[id].maxr=t[id*2+1].maxr;
if(t[id].maxr==t[id*2+1].r-t[id*2+1].l+1)
{
t[id].maxr+=t[id*2].maxr;
}
if(t[id].Imaxr==t[id*2+1].r-t[id*2+1].l+1)
{
t[id].Imaxr+=t[id*2].Imaxr;
}
t[id].maxx=max(t[id*2].maxx,max(t[id*2+1].maxx,t[id*2].maxr+t[id*2+1].maxl));
t[id].Imaxx=max(t[id*2].Imaxx,max(t[id*2+1].Imaxx,t[id*2].Imaxr+t[id*2+1].Imaxl));
}
void build(int id,int l,int r)
{
t[id].l=l;
t[id].r=r;
t[id].val=-1;
if(l==r)
{
t[id].maxl=t[id].maxr=t[id].maxx=t[id].sum=a[l];
t[id].Imaxl=t[id].Imaxr=t[id].Imaxx=a[l]^1;
return;
}
int mid=(l+r)/2;
build(id*2,l,mid);
build(id*2+1,mid+1,r);
pushup(id);
}
void change(int id)
{
swap(t[id].maxl,t[id].Imaxl);
swap(t[id].maxr,t[id].Imaxr);
swap(t[id].maxx,t[id].Imaxx);
t[id].sum=t[id].r-t[id].l+1-t[id].sum;
}
void downdate(int id)
{
if(t[id].val<=1&&t[id].val>=0)
{
int tmp;
tmp=(t[id*2].r-t[id*2].l+1);
t[id*2].val=t[id].val;
t[id*2].maxl=t[id*2].maxr=t[id*2].maxx=t[id*2].sum=tmp*t[id].val;
t[id*2].Imaxl=t[id*2].Imaxr=t[id*2].Imaxx=tmp*(t[id].val^1);
tmp=(t[id*2+1].r-t[id*2+1].l+1);
t[id*2+1].val=t[id].val;
t[id*2+1].maxl=t[id*2+1].maxr=t[id*2+1].maxx=t[id*2+1].sum=tmp*t[id].val;
t[id*2+1].Imaxl=t[id*2+1].Imaxr=t[id*2+1].Imaxx=tmp*(t[id].val^1);
}
else if(t[id].val==2)
{
if(t[id*2].val<=1&&t[id*2].val>=0)
{
int tmp=(t[id*2].r-t[id*2].l+1);
t[id*2].maxl=t[id*2].maxr=t[id*2].maxx=t[id*2].sum=tmp*(t[id*2].val^1);
t[id*2].Imaxl=t[id*2].Imaxr=t[id*2].Imaxx=tmp*t[id*2].val;
t[id*2].val^=1;
}
else if(t[id*2].val==-1)
{
change(id*2);
t[id*2].val=2;
}
else if(t[id*2].val==2)
{
change(id*2);
t[id*2].val=-1;
}
if(t[id*2+1].val<=1&&t[id*2+1].val>=0)
{
int tmp=(t[id*2+1].r-t[id*2+1].l+1);
t[id*2+1].maxl=t[id*2+1].maxr=t[id*2+1].maxx=t[id*2+1].sum=tmp*(t[id*2+1].val^1);
t[id*2+1].Imaxl=t[id*2+1].Imaxr=t[id*2+1].Imaxx=tmp*t[id*2+1].val;
t[id*2+1].val^=1;
}
else if(t[id*2+1].val==-1)
{
change(id*2+1);
t[id*2+1].val=2;
}
else if(t[id*2+1].val==2)
{
change(id*2+1);
t[id*2+1].val=-1;
}
}
t[id].val=-1;
}//恶心!!!!!
void update(int id,int l,int r,int op)
{
if(t[id].l>r || t[id].r<l)
{
return;
}
if(t[id].l>=l && t[id].r<=r)
{
if(op==0 || op==1)
{
int tmp=(t[id].r-t[id].l+1);
t[id].val=op;
t[id].maxl=t[id].maxr=t[id].maxx=t[id].sum=tmp*t[id].val;
t[id].Imaxl=t[id].Imaxr=t[id].Imaxx=t[id].sum=tmp*(t[id].val^1);
}
else if(op==2)
{
if(t[id].val==2)
{
change(id);
t[id].val=-1;//两次当成未进行过
}
else if(t[id].val<=1 && t[id].val>=0)
{
int tmp=(t[id].r-t[id].l+1);
t[id].val^=1;
t[id].maxl=t[id].maxr=t[id].maxx=t[id].sum=tmp*t[id].val;
t[id].Imaxl=t[id].Imaxr=t[id].Imaxx=tmp*(t[id].val^1);
}
else if(t[id].val=-1)
{
change(id);
t[id].val=2;
}
}
return;
}
if(t[id].val>=0)
{
downdate(id);
}
update(id*2,l,r,op);
update(id*2+1,l,r,op);
pushup(id);
}
int findsum(int id,int l,int r)
{
if(t[id].l>r || t[id].r<l)
{
return 0;
}
if(t[id].l>=l&&t[id].r<=r)
{
return t[id].sum;
}
if(t[id].val>=0)
{
downdate(id);
}
int res=findsum(id*2,l,r)+findsum(id*2+1,l,r);
return res;
}
void findmaxx(int id,int l,int r)
{
if(t[id].l>r||t[id].r<l)
{
return;
}
if(t[id].l>=l&&t[id].r<=r)
{
ans=max(ans,max(t[id].maxx,pre+t[id].maxl));
if(t[id].sum==t[id].r-t[id].l+1)
{
pre+=t[id].sum;
}
else
{
pre=t[id].maxr;
}
return;
}
if(t[id].val>=0)
{
downdate(id);
}
findmaxx(id*2,l,r);
findmaxx(id*2+1,l,r);
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
build(1,1,n);
for(int i=1;i<=m;i++)
{
int op,x,y;
cin>>op>>x>>y;
x++,y++;
if(op==1 || op==2 || op==0)
{
update(1,x,y,op);
}
else if(op==3)
{
cout<<findsum(1,x,y)<<endl;
}
else
{
ans=pre=0;
findmaxx(1,x,y);
cout<<ans<<endl;
}
}
return 0;
}
回复
共 4 条回复,欢迎继续交流。
正在加载回复...