题目大意:
给你一个长度为$n(nleq 50000)$的序列$A$,支持进行以下两种操作:
1.将区间$[l,r]$中所有数加上$c$;
2.询问区间$[l,r]$中小于$c^2$的数的个数。
思路:
分块。
对于整块的数据打标记,零散的数据直接修改。同时维护同一块中从小到大的顺序,统计时对于同一块中的数二分答案,零散的数直接统计。
1 #include<cmath> 2 #include<cstdio> 3 #include<cctype> 4 #include<algorithm> 5 #include<functional> 6 inline int getint() { 7 register char ch; 8 register bool neg=false; 9 while(!isdigit(ch=getchar())) if(ch=='-') neg=true; 10 register int x=ch^'0'; 11 while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); 12 return neg?-x:x; 13 } 14 const int N=50001; 15 int val[N],s[N],tag[N],bel[N],begin[N],end[N]; 16 inline bool cmp(const int &a,const int &b) { 17 return val[a]+tag[bel[a]]<val[b]+tag[bel[b]]; 18 } 19 inline void modify(const int &l,const int &r,const int &c) { 20 if(bel[l]==bel[r]) { 21 for(register int i=l;i<=r;i++) val[i]+=c; 22 std::sort(&s[begin[bel[l]]],&s[end[bel[l]]]+1,cmp); 23 return; 24 } 25 for(register int i=l;bel[i]==bel[l];i++) val[i]+=c; 26 std::sort(&s[begin[bel[l]]],&s[end[bel[l]]]+1,cmp); 27 for(register int i=r;bel[i]==bel[r];i--) val[i]+=c; 28 std::sort(&s[begin[bel[r]]],&s[end[bel[r]]]+1,cmp); 29 for(register int i=bel[l]+1;i<bel[r];i++) tag[i]+=c; 30 } 31 inline int query(const int &l,const int &r,const int &c) { 32 int ret=0; 33 val[0]=c*c; 34 if(bel[l]==bel[r]) { 35 for(register int i=l;i<=r;i++) { 36 if(val[i]+tag[bel[i]]<val[0]) ret++; 37 } 38 return ret; 39 } 40 for(register int i=l;bel[i]==bel[l];i++) { 41 if(val[i]+tag[bel[i]]<val[0]) ret++; 42 } 43 for(register int i=r;bel[i]==bel[r];i--) { 44 if(val[i]+tag[bel[i]]<val[0]) ret++; 45 } 46 for(register int i=bel[l]+1;i<bel[r];i++) { 47 ret+=std::lower_bound(&s[begin[i]],&s[end[i]]+1,0,cmp)-&s[begin[i]]; 48 } 49 return ret; 50 } 51 int main() { 52 const int n=getint(),block=sqrt(n); 53 for(register int i=1;i<=n;i++) { 54 val[i]=getint(); 55 bel[i]=i/block; 56 s[i]=i; 57 if(!begin[bel[i]]) begin[bel[i]]=i; 58 end[bel[i]]=i; 59 } 60 for(register int i=0;i<=bel[n];i++) { 61 std::sort(&s[begin[i]],&s[end[i]]+1,cmp); 62 } 63 for(register int i=0;i<n;i++) { 64 const int opt=getint(),l=getint(),r=getint(),c=getint(); 65 if(opt) { 66 printf("%d ",query(l,r,c)); 67 } else { 68 modify(l,r,c); 69 } 70 } 71 return 0; 72 }