数列分块
作业介绍
#include <bits/stdc++.h>
using namespace std;
const int N = 5e4+5;
#define int long long
int n,a[N],id[N],tag[N],len;
vector<int>b[N];
void update(int x) {
b[x].clear();
for (int i=(x-1)*len+1;id[i]==x;i++) {
a[i]+=tag[x];
b[x].push_back(a[i]);
}
tag[x] = 0;
sort(b[x].begin(),b[x].end());
}
void add(int l,int r,int c) {
if (id[l]==id[r]) {
for (int i=l;i<=r;i++) {
a[i]+=c;
}
update(id[l]);
}
else {
for (int i=l;id[i]==id[l];i++) {
a[i]+=c;
}
update(id[l]);
for (int i=id[l]+1;i<id[r];i++) {
tag[i]+=c;
}
for (int i=r;id[i]==id[r];i--) {
a[i]+=c;
}
update(id[r]);
}
}
int query(int l,int r,int c) {
int res = 0;
if (id[l]==id[r]) {
for (int i=l;i<=r;i++) {
if (a[i]+tag[id[i]]<c)res++;
}
return res;
}
else {
for (int i=l;id[i]==id[l];i++) {
if (a[i]+tag[id[i]]<c)res++;
}
for (int i=id[l]+1;i<id[r];i++) {
int tmp = lower_bound(b[i].begin(),b[i].end(),c-tag[i])-b[i].begin();
res+=tmp;
}
for (int i=r;id[r]==id[i];i--) {
if (a[i]+tag[id[i]]<c)res++;
}
return res;
}
}
signed main() {
cin>>n;
len = sqrt(n);
for (int i=1;i<=n;i++) {
cin>>a[i];
id[i] = (i-1)/len+1;
b[id[i]].push_back(a[i]);
}
for (int i=1;i<=(n-1)/len+1;i++) {
sort(b[i].begin(),b[i].end());
}
for (int i=1;i<=n;i++) {
int op,l,r,c;
cin>>op>>l>>r>>c;
if (op==0) {
add(l,r,c);
}
else cout<<query(l,r,c*c)<<endl;
}
return 0;
}
题目
认领作业后才可以查看作业内容。
- 状态
- 正在进行…
- 题目
- 10
- 开始时间
- 2026-7-30 0:00
- 截止时间
- 2026-8-7 23:59
- 可延期
- 24 小时