传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3343
一开始以为树套树,看到n=1e6吓尿了,看到q=3000感觉非常愉♂悦♀,于是分块大法好……
Code:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
int a[maxn],s[maxn],L[maxn],R[maxn],delta[maxn],bel[maxn];
int n,m,sqrtn,cnt;
int getint(){
int res=0;char ch=getchar();
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))res=(res<<3)+(res<<1)+ch-'0',ch=getchar();
return res;
}
int main(){
n=getint(),m=getint();sqrtn=sqrt(n);
for(int i=1;i<=n;i++)a[i]=getint(),s[i]=a[i];
int siz=0;
int l=1,r=1;
cnt=1;
for(int i=1;i<=n;i++){
if(siz<sqrtn){
siz++;r=i;bel[i]=cnt;
}else{
L[cnt]=l;R[cnt]=r;cnt++;
l=r+1;siz=0;bel[i]=cnt;
}
}
if(l<r)L[cnt]=l,R[cnt]=r;
for(int i=1;i<=cnt;i++)
sort(s+L[i],s+R[i]+1);
while(m--){
char op=getchar();while(!isalpha(op))op=getchar();
int w;l=getint(),r=getint(),w=getint();
int lx=l,rx=r;
if(op=='M'){
int ans=0;
if(bel[l]!=bel[r]){
while(l!=L[bel[l]])a[l]+=w,l++;
while(r!=R[bel[r]])a[r]+=w,r--;
if(l!=lx){
for(int i=L[bel[lx]];i<=R[bel[lx]];i++)s[i]=a[i];
sort(s+L[bel[lx]],s+R[bel[lx]]+1);
}
if(r!=rx){
for(int i=L[bel[rx]];i<=R[bel[rx]];i++)s[i]=a[i];
sort(s+L[bel[rx]],s+R[bel[rx]]+1);
}
while(bel[l]<=bel[r]&&l<=n)delta[bel[l]]+=w,l=R[bel[l]]+1;
}else{
while(l<=r)a[l++]+=w;
for(int i=L[bel[lx]];i<=R[bel[lx]];i++)s[i]=a[i];sort(s+L[bel[lx]],s+R[bel[lx]]+1);
}
}else{
int ans=0;
if(bel[l]!=bel[r]){
while(l!=L[bel[l]])ans+=a[l]>=(w-delta[bel[l]]),l++;
while(r!=R[bel[r]])ans+=a[r]>=(w-delta[bel[r]]),r--;
while(bel[l]<=bel[r]&&l<=n)ans+=R[bel[l]]-(lower_bound(s+L[bel[l]],s+R[bel[l]]+1,w-delta[bel[l]])-s)+1,l=R[bel[l]]+1;
}else
while(l<=r)ans+=a[l]>=(w-delta[bel[l]]),l++;
printf("%d\n",ans);
}
}
return 0;
}