我这样写为什么会一直TLE
#include<iostream>
#include<cstdio>
using namespace std;
typedef long long ll;
int tree[800300],a[200300],tag[800300];
char b[200005];
void psup(int x){
tree[x]=tree[x<<1]+tree[x<<1|1];
}
void build(int now,int l,int r){
if(l==r){
tree[now]=a[l];
return ;
}
int mid=(l+r)>>1;
build(now<<1,l,mid);
build(now<<1|1,mid+1,r);
psup(now);
}
void psdown(int x,int len){
if(tag[x]){
tag[x<<1]^=1;
tag[x<<1|1]^=1;
tree[x<<1]=(len-(len>>1))-tree[x<<1];
tree[x<<1|1]=(len>>1)-tree[x<<1|1];
tag[x]=0;
}
}
ll query(int p,int l,int r,int pl,int pr){
if(pl<=l&&r<=pr){
return tree[p];
}
int mid=(l+r)>>1;
ll ans=0;
if(pl<=mid){
ans+=query(p<<1,l,mid,pl,pr);
}
if(mid<pr){
ans+=query(p<<1|1,mid+1,r,pl,pr);
}
psdown(p,r-l+1);
return ans;
}
void add(int pl,int pr,int p,int l,int r){
if(l==r){
tag[p]^=1;
tree[p]=r-l+1-tree[p];
return ;
}
int mid=(l+r)>>1;
if(mid>=pl){
add(pl,pr,p<<1,l,mid);
}
if(mid<pr){
add(pl,pr,p<<1|1,mid+1,r);
}
psdown(p,r-l+1);
psup(p);
}
int main(){
int n,m,l,r,opt;
scanf("%d%d",&n,&m);
scanf("%s",b+1);
for(int i=1;i<=n;i++){
a[i]=b[i]-48;
}
build(1,1,n);
for(int i=1;i<=m;i++){
scanf("%d",&opt);
if(!opt){
scanf("%d%d",&l,&r);
add(l,r,1,1,n);
}
if(opt){
scanf("%d%d",&l,&r);
printf("%d\n",query(1,1,n,l,r));
}
}
return 0;
}