1、分块 (区间加法,查询小于x的个数)
技巧:开vector对区间sort,注意每次暴力更新的区间需要重新把数据放入vector中。
#include <algorithm> #include <iterator> #include <iostream> #include <cstring> #include <cstdlib> #include <iomanip> #include <bitset> #include <cctype> #include <cstdio> #include <string> #include <vector> #include <stack> #include <cmath> #include <queue> #include <list> #include <map> #include <set> #include <cassert> using namespace std; #define lson (l , mid , rt << 1) #define rson (mid + 1 , r , rt << 1 | 1) #define debug(x) cerr << #x << " = " << x << "\n"; #define pb push_back #define pq priority_queue typedef long long ll; typedef unsigned long long ull; //typedef __int128 bll; typedef pair<ll ,ll > pll; typedef pair<int ,int > pii; typedef pair<int,pii> p3; //priority_queue<int> q;//这是一个大根堆q //priority_queue<int,vector<int>,greater<int> >q;//这是一个小根堆q #define fi first #define se second //#define endl '\n' //#define R register #define OKC ios::sync_with_stdio(false);cin.tie(0) #define FT(A,B,C) for(int A=B;A <= C;++A) //用来压行 #define REP(i , j , k) for(int i = j ; i < k ; ++i) #define max3(a,b,c) max(max(a,b), c); #define min3(a,b,c) min(min(a,b), c); //priority_queue<int ,vector<int>, greater<int> >que; const ll mos = 0x7FFFFFFF; //2147483647 const ll nmos = 0x80000000; //-2147483648 const int inf = 0x3f3f3f3f; const ll inff = 0x3f3f3f3f3f3f3f3f; //18 const int mod = 1e9+7; const double esp = 1e-8; const double PI=acos(-1.0); const double PHI=0.61803399; //黄金分割点 const double tPHI=0.38196601; template<typename T> inline T read(T&x){ x=0;int f=0;char ch=getchar(); while (ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar(); while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return x=f?-x:x; } /*-----------------------showtime----------------------*/ const int maxn = 50009; ll a[maxn]; ll sum[maxn]; vector<ll>s[1009]; int belong[maxn]; int main(){ int n; scanf("%d", &n); for(int i=1; i<=n; i++) scanf("%lld", &a[i]); int block = sqrt(n); int num = n/block; if(n%block) num++; for(int i=1; i<=n; i++) { belong[i] = (i-1)/block + 1; s[belong[i]].pb(a[i]); } for(int i=1; i<=num; i++) sort(s[i].begin(),s[i].end()); int m = n; for(int i=1; i<=m; i++){ int op;scanf("%d", &op); if(op == 0){ int l,r; ll x; scanf("%d%d%lld", &l, &r, &x); int id = belong[l],le = (belong[l]-1)*block+1; if(belong[l] == belong[r]){ for(int i=l; i<=r; i++) a[i] += x; s[id].clear(); for(int i=le; i<= belong[l]*block; i++) s[id].pb(a[i]); sort(s[id].begin(),s[id].end()); continue; } for(int i=l; i<=belong[l]*block; i++) a[i] += x; s[id].clear(); for(int i=le; i<= belong[l]*block; i++) s[id].pb(a[i]); sort(s[id].begin(),s[id].end()); for(int i=belong[l]+1; i<=belong[r]-1; i++){ sum[i] += x; } int rid = belong[r],rle = (rid - 1) * block + 1; for(int i=(rid-1)*block+1; i<=r; i++) a[i]+=x; s[rid].clear(); for(int i=rle; i<=min(n, belong[r]*block) ; i++) s[rid].pb(a[i]); sort(s[belong[r]].begin(),s[belong[r]].end()); } else { int l,r; ll x; scanf("%d%d%lld", &l, &r, &x); int cnt = 0; if(belong[l] == belong[r]){ for(int i = l; i<= r; i++){ if(a[i] + sum[belong[i]] < 1ll*x*x) cnt++; } } else { for(int i=l; i<=belong[l]*block; i++) if(a[i] + sum[belong[i]] < 1ll*x*x) cnt++; for(int i=belong[l]+1; i<=belong[r]-1; i++){ cnt += lower_bound(s[i].begin(),s[i].end(), 1ll*x*x-sum[i]) - s[i].begin(); } for(int i=(belong[r]-1)*block+1; i<=r; i++) if(a[i] + sum[belong[i]] < 1ll*x*x) cnt++; } printf("%d\n", cnt); } } return 0; }