社区讨论
样例过了,hack过了,剩下的WA 0pts求条
P2572[SCOI2010] 序列操作参与者 2已保存回复 1
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @mmdfzuph
- 此快照首次捕获于
- 2026/03/05 20:29 5 天前
- 此快照最后确认于
- 2026/03/07 19:15 3 天前
rt
样例正确,hack也是对的,但是主测试点都是WA,找AI问了半天,结果AI都一直在注意细节部分,改了很久都没效果,进食后人也看了,似乎对我没帮助,这才来麻烦各位DL的 (qwq)
CPPc++
#include<bits/stdc++.h>
#define maxn 100086
using namespace std;
struct node{
int sum,len;
int l0,l1,r0,r1,m0,m1;
signed char ch;
bool re;
node(){
l0=l1=r0=r1=m0=m1=sum=len=0;
ch=-1;
re=0;
}
};
vector<bool>a(maxn);
vector<node>t(maxn<<2);
void push_up(int p){
node&t1=t[p<<1],&t2=t[p<<1|1];
t[p].sum=t1.sum+t2.sum;
t[p].l0=(t1.l0==t1.len?t1.l0+t2.l0:t1.l0);
t[p].l1=(t1.l1==t1.len?t1.l1+t2.l1:t1.l1);
t[p].r0=(t2.r0==t2.len?t2.r0+t1.r0:t2.r0);
t[p].r1=(t2.r1==t2.len?t2.r1+t1.r1:t2.r1);
t[p].m0=max({t[p].l0,t[p].r0,t1.m0,t2.m0,t1.r0+t2.l0});
t[p].m1=max({t[p].l1,t[p].r1,t1.m1,t2.m1,t1.r1+t2.l1});
}
void push_down(int p){
if(t[p].len==1){
t[p].ch=-1;
t[p].re=0;
return;
}
if(t[p].ch==-1&&t[p].re==0)return;
node&t1=t[p<<1],&t2=t[p<<1|1];
if(t[p].ch!=-1){
t1.ch=t2.ch=t[p].ch;
t1.re=t2.re=0;
}
if(t1.ch!=-1)
t1.ch^=t[p].re;
else
t1.re^=t[p].re;
if(t2.ch!=-1)
t2.ch^=t[p].re;
else
t2.re^=t[p].re;
auto apply=[](node&tp){
if(tp.ch==0){
tp.l0=tp.r0=tp.m0=tp.len;
tp.l1=tp.r1=tp.m1=tp.sum=0;
}
if(tp.ch==1){
tp.l0=tp.r0=tp.m0=0;
tp.l1=tp.r1=tp.m1=tp.sum=tp.len;
}
if(tp.re){
swap(tp.l0,tp.l1);
swap(tp.r0,tp.r1);
swap(tp.m0,tp.m1);
tp.sum=tp.len-tp.sum;
}
tp.re=0;
};
apply(t1);
apply(t2);
t[p].ch=-1;
t[p].re=0;
}
void build(int p,int l,int r){
if(l==r){
t[p].sum=t[p].l1=t[p].r1=t[p].m1=a[l];
t[p].l0=t[p].r0=t[p].m0=!a[l];
t[p].len=1;
return;
}
int m=(l+r)>>1;
build(p<<1,l,m);
build(p<<1|1,m+1,r);
t[p].len=t[p<<1].len+t[p<<1|1].len;
push_up(p);
}
int query_sum(int p,int l,int r,int cl,int cr){
if(cl<=l&&cr>=r)return t[p].sum;
int m=(l+r)>>1,ans=0;
push_down(p);
if(cl<=m)
ans+=query_sum(p<<1,l,m,cl,cr);
if(cr>m)
ans+=query_sum(p<<1|1,m+1,r,cl,cr);
return ans;
}
array<int,4>query_string(int p,int l,int r,int cl,int cr){
if(cl<=l&&cr>=r)return{t[p].m1,t[p].l1,t[p].r1,t[p].len};
int m=(l+r)>>1;
array<int,4>a1={},a2={},ans={};
bool sign=0;
push_down(p);
if(cl<=m){
a1=query_string(p<<1,l,m,cl,cr);
sign=1;
}
if(cr>m){
a2=query_string(p<<1|1,m+1,r,cl,cr);
if(sign){
ans[0]=max({a1[0],a2[0],a1[2]+a2[1]});
ans[1]=(a1[1]==a1[3]?a1[1]+a2[1]:a1[1]);
ans[2]=(a2[2]==a2[3]?a2[2]+a1[2]:a2[2]);
ans[3]=a1[3]+a2[3];
}else{
ans[0]=a2[0];
ans[1]=a2[1];
ans[2]=a2[2];
ans[3]=a2[3];
}
sign=0;
}
if(sign){
ans[0]=a1[0];
ans[1]=a1[1];
ans[2]=a1[2];
ans[3]=a1[3];
}
return ans;
}
void change(int p,bool s,int l,int r,int cl,int cr){
if(cl<=l&&cr>=r){
if(s){
t[p].l0=t[p].r0=t[p].m0=0;
t[p].l1=t[p].r1=t[p].m1=t[p].sum=t[p].len;
}else{
t[p].l0=t[p].r0=t[p].m0=t[p].len;
t[p].l1=t[p].r1=t[p].m1=t[p].sum=0;
}
t[p].ch=s;
t[p].re=0;
return;
}
int m=(l+r)>>1;
push_down(p);
if(cl<=m)
change(p<<1,s,l,m,cl,cr);
if(cr>m)
change(p<<1|1,s,m+1,r,cl,cr);
push_up(p);
}
void reverse(int p,int l,int r,int cl,int cr){
if(cl<=l&&cr>=r){
swap(t[p].l0,t[p].l1);
swap(t[p].r0,t[p].r1);
swap(t[p].m0,t[p].m1);
t[p].sum=t[p].len-t[p].sum;
t[p].re=!t[p].re;
return;
}
int m=(l+r)>>1;
push_down(p);
if(cl<=m)
reverse(p<<1,l,m,cl,cr);
if(cr>m)
reverse(p<<1|1,m+1,r,cl,cr);
push_up(p);
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
int n,m,i,j,l,r;
cin>>n>>m;
for(i=1;i<=n;i++){
cin>>j;
a[i]=j;
}
build(1,1,n);
for(i=1;i<=m;i++){
cin>>j>>l>>r;
l++;r++;
if(j<=1)
change(1,j,1,n,l,r);
else if(j==2)
reverse(1,1,n,l,r);
else if(j==3)
cout<<query_sum(1,1,n,l,r)<<'\n';
else if(j==4)
cout<<query_string(1,1,n,l,r)[0]<<'\n';
}
return 0;
}
没注释解释一下, 表示区间长度, 表示区间内1的数量,一个 中, 表示整段区间内最长的连续01串, 表示区间左侧连续01串长度, 表示区间右侧连续01串长度。
谢谢!
谢谢!
回复
共 1 条回复,欢迎继续交流。
正在加载回复...