QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#780964 | #7787. Maximum Rating | dodola | RE | 1ms | 7660kb | C++14 | 3.5kb | 2024-11-25 14:11:35 | 2024-11-25 14:11:36 |
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;
ll nx = 0;
struct node {
ll vl, vr;
ll pl, pr;
ll cnt, sum;
} tree[maxn];
ll tot = 1;
#define lp(p) p * 2
#define rp(p) p * 2 + 1
#define vl(p) tree[p].vl
#define vr(p) tree[p].vr
#define pl(p) tree[p].pl
#define pr(p) tree[p].pr
#define cnt(p) tree[p].cnt
#define sum(p) tree[p].sum
void pushup(ll p) {
tree[p].cnt = 0, tree[p].sum = 0;
tree[p].cnt += tree[lp(p)].cnt, tree[p].sum += tree[lp(p)].sum;
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], pl, pr, 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;
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;
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 query(ll p, ll pl, ll pr) {
if (pl(p) >= pl && pr(p) <= pr) {
return tree[p];
}
node ni = {b[pl], b[pr], -1, -1, 0, 0};
ll mid = pl(p) + (pr(p) - pl(p)) / 2;
if (pl <= mid) {
node np = query(lp(p), pl, pr);
ni.cnt += np.cnt;
ni.sum += np.sum;
}
if (pr >= mid + 1) {
node np = query(rp(p), pl, pr);
ni.cnt += np.cnt;
ni.sum += np.sum;
}
return ni;
}
ll ask(ll sum) {
ll p = 1;
// 二分确定右边界 [l,r)
// 寻找第一个大于sum的位置
ll l = 1, r = nx;
while (l < r) {
ll mid = l + (r - l) / 2;
node ni = query(1, 1, mid);
if (ni.sum <= sum) {
l = mid + 1;
} else {
r = mid;
}
}
if (l == 1) {
node nj = query(1, l, l);
if (nj.cnt == 0)
return 0;
ll ret = min(sum / (nj.sum / nj.cnt), nj.cnt);
return ret;
}
node ni = query(1, 1, l - 1);
ll ret = ni.cnt;
if (l < vr(p) + 1) {
node nj = query(1, l, l);
if (nj.cnt != 0) {
ret += min(nj.cnt, (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);
}
}
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 << ask(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;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 1ms
memory: 7656kb
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: 7660kb
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: 0
Accepted
time: 0ms
memory: 7660kb
input:
1 1 1000000000 1 1000000000
output:
1
result:
ok 1 number(s): "1"
Test #4:
score: -100
Runtime Error
input:
1 1 -1000000000 1 -1000000000