给你一个长为 N 的 01序列 A=(A1,A2,⋯,AN)。
处理 Q 个询问:第 i 个询问用三个整数 Ti,Li,Ri 表示。
Ti=1:对于每个下标 Li≤j≤Ri,把 Aj 改为 1−Aj。
Ti=2:计算序列 ALi,ALi+1,…,ARi 的逆序数。
注:序列 x1,x2,…,xk 的逆序数是满足下述条件的整数对 i,j 的数量。
NQ
A1A2…AN
T1L1R1
T2L2R2
⋮
TQLQRQ
对于每个 Ti=2 的询问,输出答案。
5 5
0 1 0 0 1
2 1 5
1 3 4
2 2 5
1 1 3
2 1 2
2
0
1
#include<bits/stdc++.h>
using namespace std;
int n,m;
struct tree{
long long v,v0,v1,l,r,tag;
};
int b[250001];
tree a[1000000];
void down(int k){
if(a[k].tag==1){
a[k*2].tag=1-a[k*2].tag;
a[k*2].v=(a[k*2].r-a[k*2].l+1)*(a[k*2].r-a[k*2].l)/2-a[k*2].v;
int vv0=a[k*2].v0;
a[k*2].v0=a[k*2].v1;
a[k*2].v1=vv0;
a[k*2+1].tag=1-a[k*2+1].tag;
a[k*2+1].v=(a[k*2+1].r-a[k*2+1].l+1)*(a[k*2+1].r-a[k*2+1].l)/2-a[k*2+1].v;
vv0=a[k*2+1].v0;
a[k*2+1].v0=a[k*2+1].v1;
a[k*2+1].v1=vv0;
a[k].tag=0;
}
}
void bulid(int x,int l,int r){
a[x].l=l;
a[x].r=r;
if(l==r){
if(b[l]==1){
a[x].v1+=1;
}else{
a[x].v0+=1;
}
a[x].v=0;
return;
}
int mid=(l+r)/2;
bulid(x*2,l,mid);
bulid(x*2+1,mid+1,r);
a[x].v0=a[x*2].v0+a[x*2+1].v0;
a[x].v1=a[x*2].v1+a[x*2+1].v1;
a[x].v=a[x*2].v+a[x*2+1].v+a[x*2].v1*a[x*2+1].v0;
return;
}
void change(int x,int l,int r){
if(l<=a[x].l&&a[x].r<=r){
a[x].tag=1-a[x].tag;
a[x].v=(a[x].r-a[x].l+1)*(a[x].r-a[x].l)/2-a[x].v;
int vv0=a[x].v0;
a[x].v0=a[x].v1;
a[x].v1=vv0;
return;
}
int mid=(l+r)/2;
down(x);
if(l<=mid){
change(2*x,l,mid);
}
if(r>mid){
change(2*x+1,mid+1,r);
}
return;
}
long long cha(int x,int l,int r){
if(l<=a[x].l&&a[x].r<=r){
return a[x].v;
}
down(x);
int mid=(l+r)/2;
int ans=0;
if(l<=mid){
ans+=cha(2*x,l,mid);
}
if(r>mid){
ans+=cha(2*x+1,mid+1,r);
}
return ans;
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>b[i];
}
bulid(1,1,n);
for(int i=0;i<m;i++){
int op,q,w;
cin>>op>>q>>w;
if(op==1){
change(1,q,w);
}else{
cout<<cha(1,q,w)<<endl;
}
}
return 0;
}
求助QwQ