题目: https://vjudge.z180.cn/contest/423156#problem/E
题意:一条线上,有房子,房子上边可能有云彩,现在可以把一片云彩轰掉,求把房子之中的人口数在没有云彩的数量最大。
解析: 用坐标维护一个线段树,用区间更新来更新没有云彩的人口,注意开longlong
代码:
#include <bits/stdc++.h>
#define lowbit(x) x&(-x)
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const ll llINF = 0x3f3f3f3f3f3f3f3f;
const int INF = 0x3f3f3f3f;
const double DINF = 1e20;
const double eps = 1e-7;
const double PI = acos(-1.0);
const int mod = 1e9 + 7;
const int N = 8e5 + 50;
int n, m, p[N], x[N], y[N], r[N];
vector<int > sct;
struct node
{
int l, r; ll cnt, c;
} tr[N * 4];
inline void Build(int l, int r, int root)
{
tr[root] = {l, r};
if (l == r) return ;
int mid = l + r >> 1;
Build(l, mid, root << 1), Build(mid + 1, r, root << 1 | 1);
}
inline void Push_up(int root)
{
if (tr[root].c == 0) {
tr[root].cnt = tr[root << 1].cnt + tr[root << 1 | 1].cnt;
} else tr[root].cnt = 0;
}
inline void Insert(int root, int idx, int val)
{
if (tr[root].l == tr[root].r) {
tr[root].cnt += val;
return ;
}
int mid = tr[root].l + tr[root].r >> 1;
if (idx <= mid) Insert(root << 1, idx, val);
else Insert(root << 1 | 1, idx, val);
Push_up(root);
}
inline void Push_down(int root)
{
tr[root << 1].c = tr[root << 1 | 1].c = tr[root].c;
}
inline void Modify(int root, int L, int R, int val)
{
if (tr[root].l >= L && tr[root].r <= R) {
tr[root].c += val;
Push_up(root);
return ;
}
int mid = tr[root].l + tr[root].r >> 1;
if (L <= mid) Modify(root << 1, L, R, val);
if (R > mid) Modify(root << 1 | 1, L, R, val);
Push_up(root);
}
inline int Get(int x)
{
return lower_bound(sct.begin(), sct.end(), x) - sct.begin();
}
int main()
{
//ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
scanf("%d", &n);
for (int i = 1; i <= n; i++) scanf("%d", &p[i]);
for (int i = 1; i <= n; i++) {
scanf("%d", &x[i]);
sct.push_back(x[i]);
}
scanf("%d", &m);
for (int i = 1; i <= m; i++) scanf("%d", &y[i]);
for (int i = 1; i <= m; i++) {
scanf("%d", &r[i]);
sct.push_back(y[i] - r[i]), sct.push_back(y[i] + r[i]);
}
sort(sct.begin(), sct.end());
sct.erase(unique(sct.begin(), sct.end()), sct.end());
int len = sct.size();
Build(0, len - 1, 1);
for (int i = 1; i <= n; i++) {
Insert(1, Get(x[i]), p[i]);
}
ll ans = 0;
for (int i = 1; i <= m; i++) {
Modify(1, Get(y[i] - r[i]), Get(y[i] + r[i]), 1);
}
for (int i = 1; i <= m; i++) {
Modify(1, Get(y[i] - r[i]), Get(y[i] + r[i]), -1);
ans = max(ans, tr[1].cnt);
Modify(1, Get(y[i] - r[i]), Get(y[i] + r[i]), 1);
}
printf("%lld\n", ans);
return 0;
}