QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#779621 | #7787. Maximum Rating | dodola | RE | 1ms | 7852kb | C++14 | 3.6kb | 2024-11-24 20:24:17 | 2024-11-24 20:24:17 |
Judging History
answer
#include <bits/stdc++.h>
// #define x first
// #define y second
using namespace std;
typedef double ld;
typedef unsigned long ul;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> pll;
const int maxn = 8e5 + 50;
const ll inf = 0x3f3f3f3f3f3f;
const vector<pll> dxy = {{-1, 0}, {1, 0}, {0, 1}, {0, -1}};
ll a[maxn], b[maxn];
multiset<ll> st;
struct node {
ll vl, vr;
ll lp, rp;
ll cnt, sum;
} tree[maxn];
ll tot = 1;
#define lp(p) tree[p].lp
#define rp(p) tree[p].rp
#define vl(p) tree[p].vl
#define vr(p) tree[p].vr
#define cnt(p) tree[p].cnt
#define sum(p) tree[p].sum
void pushup(ll p) {
tree[p].cnt = 0, tree[p].sum = 0;
if (lp(p) != -1)
tree[p].cnt += tree[lp(p)].cnt, tree[p].sum += tree[lp(p)].sum;
if (rp(p) != -1)
tree[p].cnt += tree[rp(p)].cnt, tree[p].sum += tree[rp(p)].sum;
}
void build(ll p, ll pl, ll pr) {
tree[p] = {
b[pl], b[pr], -1, -1, 0, 0,
};
if (pl == pr) {
tree[p].cnt = st.count(b[pl]);
tree[p].sum = b[pl] * tree[p].cnt;
return;
}
ll mid = pl + (pr - pl) / 2;
tree[p].lp = ++tot, tree[p].rp = ++tot;
build(lp(p), pl, mid);
build(rp(p), mid + 1, pr);
pushup(p);
}
void update(ll p, ll num, ll c) {
if (tree[p].vl == tree[p].vr) {
tree[p].cnt += c;
tree[p].sum = tree[p].cnt * num;
// pushup(p);
return;
}
ll mid = vl(p) + (vr(p) - vl(p)) / 2;
if (num <= mid)
update(lp(p), num, c);
else
update(rp(p), num, c);
pushup(p);
}
node getsum(ll p, ll l, ll r) {
if (vl(p) >= l && vr(p) <= r) {
return tree[p];
}
node ni = {l, r, -1, -1, 0, 0};
ll mid = vl(p) + (vr(p) - vl(p)) / 2;
if (l <= mid) {
node np = getsum(lp(p), l, r);
ni.cnt += np.cnt;
ni.sum += np.sum;
}
if (r >= mid + 1) {
node np = getsum(rp(p), l, r);
ni.cnt += np.cnt;
ni.sum += np.sum;
}
return ni;
}
ll query(ll sum) {
ll p = 1;
// 二分确定右边界 [l,r)
// 寻找第一个大于sum的位置
ll l = 1, r = vr(p) + 1;
while (l < r) {
ll mid = l + (r - l) / 2;
if (mid == 0) {
break;
}
node ni = getsum(1, 1, mid);
if (ni.sum <= sum) {
l = mid + 1;
} else {
r = mid;
}
}
if (l == 1) {
node nj = getsum(1, l, l);
if (nj.cnt == 0)
return 0;
return sum / (nj.sum / nj.cnt);
}
node ni = getsum(1, 1, l - 1);
ll ret = ni.cnt;
if (l < vr(p) + 1) {
node nj = getsum(1, l, l);
if (nj.cnt != 0)
ret += (sum - ni.sum) / (nj.sum / nj.cnt);
}
return ret;
}
void solve() {
ll n, q;
cin >> n >> q;
st.clear();
ll sum = 0;
set<ll> stb;
for (ll i = 1; i <= n; i++) {
cin >> a[i];
if (a[i] > 0) {
st.insert(a[i]);
stb.insert(a[i]);
} else {
sum += -a[i];
}
}
vector<pll> ve(q);
for (ll i = 0; i < q; i++) {
cin >> ve[i].first >> ve[i].second;
if (ve[i].second > 0) {
stb.insert(ve[i].second);
}
}
ll nx = 0;
for (auto i : stb) {
b[++nx] = i;
}
build(1, 1, nx);
for (ll i = 0; i < q; i++) {
auto [x, v] = ve[i];
if (a[x] > 0) {
update(1, a[x], -1);
} else {
sum -= -a[x];
}
if (v > 0) {
update(1, v, 1);
} else {
sum += -v;
}
cout << query(sum) + 1 << '\n';
a[x] = v;
}
}
void init() {
// init_primes();
}
int main(void) {
ios::sync_with_stdio(false);
cin.tie(0);
init();
int _t = 1;
// cin >> _t;
// cin.get();
while (_t--)
solve();
return 0;
}
詳細信息
Test #1:
score: 100
Accepted
time: 1ms
memory: 7708kb
input:
3 5 1 2 3 3 4 2 -2 1 -3 3 1 2 1
output:
1 2 2 2 3
result:
ok 5 number(s): "1 2 2 2 3"
Test #2:
score: 0
Accepted
time: 1ms
memory: 7852kb
input:
3 5 1 2 3 3 4 2 -2 1 3 3 1 2 1
output:
1 2 1 2 1
result:
ok 5 number(s): "1 2 1 2 1"
Test #3:
score: -100
Runtime Error
input:
1 1 1000000000 1 1000000000