rt,线段树二分写法。不要告诉我线段树换成树状数组。
(先把 wa 的调完了我再试试卡常/kel)
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pii pair<int, int>
const int N = 2e6 + 5;
int q, opt[N], t[N], x[N], y[N], k[N], ps[N], tot, cnt[3];
pair<int, int> ans;
map<int, bool> mp;
map<int, int> mr;
struct node
{
int l, r, sum;
} tree[2][N << 2];
void build(int o, int l, int r, int x)
{
tree[o][x] = {l, r, 0};
if(l == r) return;
int mid = (l + r) >> 1;
build(o, l, mid, x << 1);
build(o, mid + 1, r, x << 1 | 1);
return;
}
inline void pushup(int o, int x)
{
tree[o][x].sum = tree[o][x << 1].sum + tree[o][x << 1 | 1].sum;
}
void update(int o, int p, int k, int x)
{
if(p == tree[o][x].l && tree[o][x].r == p)
return (void) (tree[o][x].sum += k);
int mid = (tree[o][x].l + tree[o][x].r) >> 1;
if(p <= mid) update(o, p, k, x << 1);
if(mid < p) update(o, p, k, x << 1 | 1);
pushup(o, x);
return;
}
void getmax(pii &a, pii b)
{
if(b.second > a.second) a = b;
else if(b.second == a.second && b.first > a.first) a = b;
}
void query(int x, int d0, int d1) // f(0) >= f(1) 的最小的位置
{
// cout << ps[tree[0][x].l] << ' ' << ps[tree[0][x].r] << " | " << tree[0][x].sum << '+' << d0 << " | " << tree[1][x].sum << '+' << d1 << '\n';
if(tree[0][x].l == tree[0][x].r)
getmax(ans, (tree[0][x].sum + d0 >= tree[1][x].sum + d1) ? (pii) {ps[tree[0][x].l], 2ll * (tree[1][x].sum + d1)} : (pii) {-1, -1});
else if(tree[0][x << 1].sum + d0 >= tree[1][x << 1 | 1].sum + d1)
{
getmax(ans, (pii) {ps[tree[0][x << 1 | 1].l], (tree[1][x << 1 | 1].sum + d1) * 2ll});
query(x << 1, d0, d1 + tree[1][x << 1 | 1].sum);
}
else query(x << 1 | 1, d0 + tree[0][x << 1].sum, d1);
}
void query2(int x, int d0, int d1) // f(1) >= f(0) 的最大的位置
{
// cout << ps[tree[0][x].l] << ' ' << ps[tree[0][x].r] << " | " << tree[0][x].sum << '+' << d0 << " | " << tree[1][x].sum << '+' << d1 << '\n';
if(tree[0][x].l == tree[0][x].r)
getmax(ans, (tree[1][x].sum + d1 >= tree[0][x].sum + d0) ? (pii) {ps[tree[1][x].l], 2ll * (tree[0][x].sum + d0)} : (pii) {-1, -1});
else if(tree[1][x << 1 | 1].sum + d1 >= tree[0][x << 1].sum + d0)
{
// cout << ps[tree[0][x << 1].r] << '.';
getmax(ans, (pii) {ps[tree[0][x << 1].r], (tree[0][x << 1].sum + d0) * 2ll});
query2(x << 1 | 1, d0 + tree[0][x << 1].sum, d1);
}
else query2(x << 1, d0, d1 + tree[1][x << 1 | 1].sum);
}
signed main()
{
ios :: sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin >> q;
for(int i = 1; i <= q; i++)
{
cin >> opt[i];
if(opt[i] == 1) cin >> t[i] >> x[i] >> y[i], mp[x[i]] = 1;
else cin >> k[i];
}
for(auto p : mp) mr[p.first] = ++tot, ps[tot] = p.first;
mr[2e6 + 1] = ++tot, ps[tot] = 2e6 + 1;
for(int o = 0; o <= 1; o++) build(o, 1, tot, 1);
for(int i = 1; i <= q; i++)
{
if(opt[i] == 1) update(t[i], mr[x[i]], y[i], 1), cnt[t[i]]++;
else update(t[k[i]], mr[x[k[i]]], -y[k[i]], 1), cnt[t[i]]--;
if(min(cnt[0], cnt[1]) == 0) cout << "Peace\n";
else
{
ans = {0, 0};
query(1, 0, 0), query2(1, 0, 0);
// if(n1.second > n2.second) cout << n1.first << ' ' << n1.second << '\n';
// else if(n1.second == n2.second) cout << max(n1.first, n2.first) << ' ' << n1.second << '\n';
// else cout << n2.first << ' ' << n2.second << '\n';
cout << ans.first << ' ' << ans.second << '\n';
// cout << n1.first <<' ' << n1.second << "; ";
// cout << n2.first <<' ' << n2.second << '\n';
}
// cout << query(1, 0, 0) << '\n';
}
return 0;
}
/*
100 100
103 300
// 100 400
// 103 150
102 150
101 100
104 350
*/