标签:Meteors int void POI2011 rg inline ql
「POI2011」Meteors
传送门
整体二分,树状数组实现区间修改单点查询,然后注意修改是在环上的。
参考代码:
#include <cstdio>
#include <vector>
#define rg register
#define file(x) freopen(x".in", "r", stdin), freopen(x".out", "w", stdout)
using namespace std;
template < class T > inline void read(T& s) {
s = 0; rg int f = 0; rg char c = getchar();
while ('0' > c || c > '9') f |= c == '-', c = getchar();
while ('0' <= c && c <= '9') s = s * 10 + c - 48, c = getchar();
s = f ? -s : s;
}
const int _ = 9e5 + 5;
int n, m, k, p[_], tr[_], ans[_]; vector < int > pos[_];
int num; struct node { int opt, l, r, x, id; } t[_], tt1[_], tt2[_];
inline void update(int x, int v) { for (rg int i = x; i <= m; i += i & -i) tr[i] += v; }
inline int query(int x) { int res = 0; for (rg int i = x; i >= 1; i -= i & -i) res += tr[i]; return res; }
inline void solve(int ql, int qr, int l, int r) {
if (ql > qr || l > r) return ;
if (l == r) { for (rg int i = ql; i <= qr; ++i) if (t[i].opt == 0) ans[t[i].id] = l; return ; }
int mid = (l + r) >> 1, p1 = 0, p2 = 0;
for (rg int i = ql; i <= qr; ++i) {
if (t[i].opt != 0) {
if (t[i].id <= mid) {
if (t[i].opt == 1) update(t[i].l, t[i].x), update(t[i].r + 1, -t[i].x);
else update(1, t[i].x), update(t[i].r + 1, -t[i].x), update(t[i].l, t[i].x);
tt1[++p1] = t[i];
} else tt2[++p2] = t[i];
} else {
int cnt = 0;
for (rg int j = 0; j < pos[t[i].id].size(); ++j) {
cnt += query(pos[t[i].id][j]); if (cnt >= t[i].x) break ;
}
if (cnt >= t[i].x) tt1[++p1] = t[i]; else t[i].x -= cnt, tt2[++p2] = t[i];
}
}
for (rg int i = 1; i <= p1; ++i)
if (tt1[i].opt != 0) {
if (tt1[i].opt == 1) update(tt1[i].l, -tt1[i].x), update(tt1[i].r + 1, tt1[i].x);
else update(1, -tt1[i].x), update(tt1[i].r + 1, tt1[i].x), update(tt1[i].l, -tt1[i].x);
}
for (rg int i = 1; i <= p1; ++i) t[ql + i - 1] = tt1[i];
for (rg int i = 1; i <= p2; ++i) t[ql + p1 + i - 1] = tt2[i];
solve(ql, ql + p1 - 1, l, mid), solve(ql + p1, qr, mid + 1, r);
}
int main() {
read(n), read(m);
for (rg int x, i = 1; i <= m; ++i) read(x), pos[x].push_back(i);
for (rg int i = 1; i <= n; ++i) read(p[i]);
read(k);
for (rg int opt, l, r, x, i = 1; i <= k; ++i) {
read(l), read(r), read(x);
if (l <= r) t[++num] = (node) { 1, l, r, x, i }; else t[++num] = (node) { 2, l, r, x, i };
}
for (rg int i = 1; i <= n; ++i) t[++num] = (node) { 0, 0, 0, p[i], i };
solve(1, num, 1, k + 1);
for (rg int i = 1; i <= n; ++i) if (ans[i] == k + 1) puts("NIE"); else printf("%d\n", ans[i]);
return 0;
}
标签:Meteors,int,void,POI2011,rg,inline,ql 来源: https://www.cnblogs.com/zsbzsb/p/12231710.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。