哎哟,最后三个点A了,其他有几十万行WA的,写的树套树差分
#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read(){
int x=0;bool f=0;char ch=getchar();
while(ch<'0'||ch>'9')f^=(ch=='-'),ch=getchar();
while('0'<=ch&&ch<='9')x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return f?-x:x;
}
const int Maxn=3e5+5;
int n,q,a[Maxn];
struct node{
int l,r;
inline bool operator<(const node&b)const{return r<b.r;}
};
multiset<node>s;
int root[Maxn<<2],cnt;
struct Tree{int ls,rs,data,val;}t[Maxn*200];
void change1(int&x,int l,int r,int d,int p){
if(!x)x=++cnt;t[x].data+=(p<0?-1:1);t[x].val+=p;if(l==r)return;
int mid=l+r>>1;
if(mid>=d)change1(t[x].ls,l,mid,d,p);
else change1(t[x].rs,mid+1,r,d,p);
}
int query1(int x,int l,int r,int L,int R){
if(L<=l&&r<=R)return t[x].data;
int mid=l+r>>1,res=0;
if(mid>=L)res=query1(t[x].ls,l,mid,L,R);
if(mid<R)res+=query1(t[x].rs,mid+1,r,L,R);
return res;
}
int query1_(int x,int l,int r,int L,int R){
if(L<=l&&r<=R)return t[x].val;
int mid=l+r>>1,res=0;
if(mid>=L)res=query1_(t[x].ls,l,mid,L,R);
if(mid<R)res+=query1_(t[x].rs,mid+1,r,L,R);
return res;
}
void change(int x,int l,int r,int d1,int d2,int p){
change1(root[x],1,n,d2,p);if(l==r)return;
int mid=l+r>>1;
if(mid>=d1)change(x<<1,l,mid,d1,d2,p);
else change(x<<1|1,mid+1,r,d1,d2,p);
}
int query(int x,int l,int r,int L,int R,int L1,int R1){
if(L<=l&&r<=R)return query1(root[x],1,n,L1,R1);
int mid=l+r>>1,res=0;
if(mid>=L)res=query(x<<1,l,mid,L,R,L1,R1);
if(mid<R)res+=query(x<<1|1,mid+1,r,L,R,L1,R1);
return res;
}
int query_(int x,int l,int r,int L,int R,int L1,int R1){
if(L<=l&&r<=R)return query1_(root[x],1,n,L1,R1);
int mid=l+r>>1,res=0;
if(mid>=L)res=query_(x<<1,l,mid,L,R,L1,R1);
if(mid<R)res+=query_(x<<1|1,mid+1,r,L,R,L1,R1);
return res;
}
signed main(){
n=read();q=read();
int l=1;
for(int i=1;i<=n;i++){
scanf("%1d",&a[i]);
if(!a[i]){
if(l<=i-1)s.insert({l,i-1}),change(1,1,n,l,i-1,0);
l=i+1;
}
}
if(l<=n)s.insert({l,n}),change(1,1,n,l,n,0);
char ch[114];
for(int k=1;k<=q;k++){
scanf("%s",ch);
if(ch[0]=='t'){
int i=read();
a[i]^=1;
if(a[i]){
int l=i,r=i;
if(i>1&&a[i-1]==1){
auto it=s.lower_bound({0,i-1});
change(1,1,n,(*it).l,(*it).r,-k);
s.erase(*it);
l=(*it).l;
}
if(i<n&&a[i+1]==1){
auto it=s.lower_bound({0,i+1});
change(1,1,n,(*it).l,(*it).r,-k);
s.erase(*it);
r=(*it).r;
}
s.insert({l,r});change(1,1,n,l,r,k);//printf("%d %d\n",l,r);
}
else{
auto it=s.lower_bound({0,i});
// if(it==s.end())return -1;
// if(it==s.end())continue;
if((*it).l<=i-1)change(1,1,n,(*it).l,i-1,k),s.insert({(*it).l,i-1});
if(i+1<=(*it).r)change(1,1,n,i+1,(*it).r,k),s.insert({i+1,(*it).r});
change(1,1,n,(*it).l,(*it).r,-k);s.erase(*it);
}
}
else{
int a=read(),b=read()-1;
printf("%lld\n",query(1,1,n,1,a,b,n)*k-query_(1,1,n,1,a,b,n));
}
}
return 0;
}