提交时间:2022-02-09 22:56:11
运行 ID: 44721
#include <bits/stdc++.h> using namespace std; const int MAXN=50008; int n,blocksize; int arr[MAXN], brr[MAXN], tag[MAXN]; vector<int> group[MAXN]; int fr(); void Reset(int k) { group[k].clear(); // 清空 第 k 块 int l=(k-1)*blocksize+1; //第 k 块的区间[l,r] int r=min(k*blocksize,n); for (int i=l; i<=r; i++) group[k].emplace_back( arr[i] ); // 更新 group[k] sort( group[k].begin(), group[k].end() ); // 重新排序 } void Update(int l, int r, int c) { int R=min(r, brr[l]*blocksize ); //更新 l 所在不完整块的数据 for (int i=l; i<=R; i++) arr[i]+= c; Reset( brr[l] ); // 更新块 brr[l] if ( brr[l] != brr[r] ) // l, r 不在同一块 { int L=( brr[r]-1)*blocksize+1; for (int i=L; i<=r; i++) //更新 r 所在不完整块的数据 arr[i]+=c; Reset( brr[r] ); // 更新块 brr[r] } for (int i=brr[l]+1; i<=brr[r]-1; i++) //添加懒惰标签( l, r 跨越的完整块 ) tag[i]+=c; } int Find(int l, int r, int c) { int cnt=0; int R=min(r, brr[l]*blocksize ); for (int i=l; i<=R; i++) //比较 l 所在不完整块的数据 if ( arr[i] + tag[ brr[i] ] < c ) cnt++; if ( brr[l] != brr[r] ) // l, r 不在同一块 { int L= (brr[r]-1)*blocksize +1 ; for (int i=L; i<=r; i++) //比较 r所在不完整块的数据 if ( arr[i] + tag[ brr[i] ] < c ) cnt++; } for (int i=brr[l]+1; i<=brr[r]-1; i++) //二分查找( l, r 跨越的完整块 ) cnt+=lower_bound( group[i].begin(), group[i].end(), c-tag[i] ) - group[i].begin(); return cnt; } int main() { // freopen("array10.in","r",stdin); // freopen("array10.out","w",stdout); int k,cmd,l,r,c; n=fr(); blocksize=sqrt(n); for (int i=1; i<=n; i++) // 分块, 共有 k= n/blocksize 块; { arr[i]=fr(); k=(i-1)/blocksize+1; // 块序号k brr[i]=k; // brr[i]记录 i 属于第 k块 group[k].emplace_back( arr[i] ); //存入 group[k] } for (int i=1; i<=k; i++) // 对每块排序 sort( group[i].begin(), group[i].end() ); for (int i=1; i<=n; i++) { cmd=fr(), l=fr(), r=fr(), c=fr(); if (cmd==0) Update(l, r, c); // 更新数据 else cout<<Find(l, r, c*c)<<endl; // 查询 } return 0; } int fr(){ int x=0,flag=1; char ch=getchar(); while( ch<'0'||ch>'9' ) { if( ch=='-') flag=-1; ch=getchar(); } while( ch>='0'&& ch<='9' ) { x= x*10 + ch- '0'; ch=getchar(); } return x*flag; }