1 条题解
-
0
力竭,97分极限。
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int MAXN = 300005; int n, m, k; int owner[MAXN]; ll need[MAXN]; int ans[MAXN]; vector<int> stations[MAXN]; struct Event { int l, r; ll a; } rain[MAXN]; ll bit[MAXN]; void add(int x, ll v) { for (; x <= m; x += x & -x) bit[x] += v; } ll query(int x) { ll res = 0; for (; x; x -= x & -x) res += bit[x]; return res; } void apply(int id, int coeff) { int l = rain[id].l, r = rain[id].r; ll a = rain[id].a * coeff; if (l <= r) { add(l, a); if (r + 1 <= m) add(r + 1, -a); } else { add(1, a); if (r + 1 <= m) add(r + 1, -a); add(l, a); } } void solve(int l, int r, vector<int>& ids) { if (l > r || ids.empty()) return; if (l == r) { for (int id : ids) ans[id] = l; return; } int mid = (l + r) >> 1; // 将[l, mid]的陨石雨加入 for (int i = l; i <= mid; ++i) apply(i, 1); vector<int> leftIds, rightIds; for (int id : ids) { ll sum = 0; for (int pos : stations[id]) { sum += query(pos); if (sum >= need[id]) break; } if (sum >= need[id]) { leftIds.push_back(id); } else { rightIds.push_back(id); } } // 撤销[l, mid]的陨石雨 for (int i = l; i <= mid; ++i) apply(i, -1); solve(l, mid, leftIds); // 注意:递归右半边时,需要将[l, mid]的陨石雨再次加入 for (int i = l; i <= mid; ++i) apply(i, 1); solve(mid + 1, r, rightIds); // 撤销[l, mid]的陨石雨,恢复状态 for (int i = l; i <= mid; ++i) apply(i, -1); } int main() { scanf("%d%d", &n, &m); for (int i = 1; i <= m; ++i) { int o; scanf("%d", &o); stations[o].push_back(i); } for (int i = 1; i <= n; ++i) { scanf("%lld", &need[i]); } scanf("%d", &k); for (int i = 1; i <= k; ++i) { scanf("%d%d%lld", &rain[i].l, &rain[i].r, &rain[i].a); } // 添加一场虚拟陨石雨,用于处理无解 rain[k + 1] = {1, 1, 0}; // 注意:这里可以任意设置,因为雨量为0 ++k; vector<int> allIds; for (int i = 1; i <= n; ++i) { allIds.push_back(i); ans[i] = k + 1; // 初始化为k+1表示无解 } solve(1, k, allIds); for (int i = 1; i <= n; ++i) { if (ans[i] == k) { // 注意:k是虚拟陨石雨的编号 printf("NIE\n"); } else { printf("%d\n", ans[i]); } } return 0; }
- 1
信息
- ID
- 179
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 10
- 标签
- 递交数
- 6
- 已通过
- 0
- 上传者