题目大意
给定一个数列,支持区间加法,求区间大于等于 (c) 的数的个数
思路
分块裸题
散的个体单独加,询问时单独判
对于一整块加则打上标记
要求块中大于等于 (c) 的数的个数
我们不妨将块中元素排序,二分求解即可
为了保证时间复杂度
我们在修改的时候排序
因为同时加一个数,相对大小不变,不需排序
那么我们只有排暴力更改的散的个体所在的块就可以了
时间复杂度 (O(nsqrt nlog n))
(Code)
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int N = 1e6 + 5;
int n , m , a[N] , t[N] , belong[N] , st[N] , ed[N] , tag[N] , num;
inline int read()
{
int res = 0;
char ch = getchar();
while (ch < '0' || ch > '9') ch = getchar();
while (ch >= '0' && ch <= '9') res = res * 10 + ch - '0' , ch = getchar();
return res;
}
inline void Sort(int x)
{
for(register int i = st[x]; i <= ed[x]; i++) t[i] = a[i];
sort(t + st[x] , t + ed[x] + 1);
}
inline void prepare()
{
num = (int)sqrt(n);
for(register int i = 1; i <= num; i++) st[i] = n / num * (i - 1) + 1 , ed[i] = n / num * i;
ed[num] = n;
for(register int i = 1; i <= num; i++)
{
for(register int j = st[i]; j <= ed[i]; j++) belong[j] = i;
Sort(i);
}
}
inline void change(int l , int r , int c)
{
int x = belong[l] , y = belong[r];
if (x == y)
{
for(register int i = l; i <= r; i++) a[i] += c;
Sort(x);
return;
}
for(register int i = l; i <= ed[x]; i++) a[i] += c;
for(register int i = st[y]; i <= r; i++) a[i] += c;
for(register int i = x + 1; i <= y - 1; i++) tag[i] += c;
Sort(x) , Sort(y);
}
inline int query(int l , int r , int c)
{
int x = belong[l] , y = belong[r] , res = 0;
if (x == y)
{
for(register int i = l; i <= r; i++)
if (a[i] + tag[x] >= c) res++;
return res;
}
for(register int i = l; i <= ed[x]; i++)
if (a[i] + tag[x] >= c) res++;
for(register int i = st[y]; i <= r; i++)
if (a[i] + tag[y] >= c) res++;
for(register int i = x + 1; i <= y - 1; i++)
res += ed[i] - (lower_bound(t + st[i] , t + ed[i] + 1 , c - tag[i]) - t) + 1;
return res;
}
int main()
{
n = read() , m = read();
for(register int i = 1; i <= n; i++) a[i] = read();
prepare();
char opt[2];
int x , y , z;
for(register int i = 1; i <= m; i++)
{
scanf("%s" , opt);
x = read() , y = read() , z = read();
if (opt[0] == 'A') printf("%d
" , query(x , y , z));
else change(x , y , z);
}
}