QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#666816 | #7787. Maximum Rating | absabs | WA | 2ms | 7844kb | C++23 | 5.8kb | 2024-10-22 20:04:06 | 2024-10-22 20:04:10 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl "\n"
#define ull unsigned long long
#define ms(x, y) memset(x, y, sizeof x);
#define debug(x) cout << #x << " = " << x << endl;
#define ios ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
#define fre \
freopen("input.txt", "r", stdin); \
freopen("output.txt", "w", stdout);
const int mod = 998244353;
const int inf = 0x3f3f3f3f3f3f3f3f;
const int N = 1e6 + 10;
const double esp = 1e-6;
const ull MOD1 = 1610612741;
const ull MOD2 = 805306457;
const ull BASE1 = 1331;
const ull BASE2 = 131;
#define pre(i, a, b) for (int i = a; i <= b; i++)
#define rep(i, a, b) for (int i = a; i >= b; i--)
#define all(x) (x).begin(), (x).end()
char *p1, *p2, buf[100000]; // 快读和同步流二者只能选一个
#define nc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1++)
int read()
{
int x = 0, f = 1;
char ch = nc();
while (ch < 48 || ch > 57)
{
if (ch == '-')
f = -1;
ch = nc();
}
while (ch >= 48 && ch <= 57)
x = x * 10 + ch - 48, ch = nc();
return x * f;
}
void write(int x)
{
if (x < 0)
putchar('-'), x = -x;
if (x > 9)
write(x / 10);
putchar(x % 10 + '0');
return;
}
//每轮之后 a[i] 都会加到 now 上,当前now > 当前最高评价时需要更新最高评价
//找出最小值和最大值即可,两者之间数据一定是可以到达的
//最大的一定是正数递增先排,答案就是正数个数
//最小一定是先负数,在正数递增,答案是前缀和大于 0 之后的后续位置
#define pa tr[u]
#define ls tr[u << 1]
#define rs tr[u << 1 | 1]
int n,m,a[N];
pair<int,int> q[N];
vector<int> ve;//离散化
//难度在于数据是变化的,需要动态维护,因为存在负数,树状数组处理可能会很麻烦,直接转换为权值线段树
struct node
{
int x,sum;//当前权值左边的个数和区间和
}tr[N << 2];
node mer(node l,node r)
{
node res = {0,0};
res.x = l.x + r.x;
res.sum = l.sum + r.sum;
return res;
}
void build(int u,int l,int r)
{
if(l > r) return;
if(l == r)
{
pa.x = pa.sum = 0;
return ;
}
int mid = l + r >> 1;
build(u << 1,l,mid);
build(u << 1,mid + 1,r);
pa = mer(ls,rs);
}
void modify(int u,int l,int r,int L,int R) //单点修改,先删除后修改
{
if(l > r) return ;
if(L <= l && r <= R)
{
pa.x ++;
pa.sum += ve[L - 1];
// cout << L << " ccccc " << pa.x << " " << pa.sum << endl;
return ;
}
int mid = l + r >> 1;
if(L <= mid)
modify(u << 1,l,mid,L,R);
if(R > mid)
modify(u << 1 | 1,mid + 1,r,L,R);
pa = mer(ls,rs);
return ;
}
void del(int u,int l,int r,int L,int R)
{
if(l > r) return ;
// cout << L << " dddddd " << R << endl;
// cout << l << " " << r << " " << L << " " << R << endl;
if(L <= l && r <= R)
{
pa.x --;
pa.sum -= ve[L - 1];
// cout << L << " ddddd " << pa.x << " " << pa.sum << endl;
return ;
}
int mid = l + r >> 1;
if(L <= mid)
del(u << 1,l,mid,L,R);
if(R > mid)
del(u << 1 | 1,mid + 1,r,L,R);
pa = mer(ls,rs);
return ;
}
int query(int u,int l,int r,int x)//二分查找目前的最小值,最大值可以实时维护
{//寻找目前前缀和大于 0 的位置
if(l > r) return -1;
if(tr[1].sum <= x) return -1;//找不到
if(l == r)
return x / ve[l - 1] + 1;//此时是单点,判断这个点是整数是负数??
int mid = l + r >> 1;
if(ls.sum > x) return query(u << 1,l,mid,x);
else return ls.x + query(u << 1 | 1,mid + 1,r,x - ls.sum);
}
int find(int x)
{
return lower_bound(ve.begin(),ve.end(),x) - ve.begin() + 1;
}
void solve()
{
cin >> n >> m;
int mx = 0,sum = 0;
pre(i,1,n)
{
cin >> a[i];
if(a[i] > 0) mx ++,ve.push_back(a[i]);
else sum -= a[i];
}
pre(i,1,m)
{
cin >> q[i].first >> q[i].second;
if(q[i].second > 0)
ve.push_back(q[i].second);
}
sort(ve.begin(),ve.end());
ve.erase(unique(ve.begin(),ve.end()),ve.end());
int total = ve.size();
// cout << total << endl;
build(1,1,total);
pre(i,1,n)
{
if(a[i] <= 0)
{
sum -= a[i];//负数直接使用sum统计即可
}
else //权值线段树只保留正数
{
a[i] = find(a[i]);//离散化到下标即可
modify(1,1,total,a[i],a[i]);
}
}
pre(i,1,m)
{
if(a[q[i].first] <= 0)
{
sum += a[q[i].first];
}
else
{
// cout << "this" << " " << q[i].first << " " << a[q[i].first] << endl;
del(1,1,total,a[q[i].first],a[q[i].first]);
mx -- ;
}
if(q[i].second <= 0)
sum -= q[i].second ,a[q[i].first] = q[i].second;
else
{
a[q[i].first] = find(q[i].second);
modify(1,1,total,a[q[i].first],a[q[i].first]);
mx ++ ;
}
int res = query(1,1,total,sum);//需要多少个正数在前面
// cout << i << " " << res << " " << tr[1].sum << endl;
cout << mx - (res == -1 ? 0 : mx - res + 1) + 1 << endl;
}
}
// #define LOCAL
signed main()
{
ios
// fre
#ifdef LOCAL
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
auto start = std::chrono::high_resolution_clock::now();
#endif
int t = 1;
// cin >> t;
while (t--)
solve();
#ifdef LOCAL
auto end = std::chrono::high_resolution_clock::now();
cout << "Execution time: "
<< std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count()
<< " ms" << '\n';
#endif
return 0;
}
详细
Test #1:
score: 100
Accepted
time: 0ms
memory: 5684kb
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: 5616kb
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: 1ms
memory: 5764kb
input:
1 1 1000000000 1 1000000000
output:
1
result:
ok 1 number(s): "1"
Test #4:
score: 0
Accepted
time: 1ms
memory: 7652kb
input:
1 1 -1000000000 1 -1000000000
output:
1
result:
ok 1 number(s): "1"
Test #5:
score: 0
Accepted
time: 1ms
memory: 5800kb
input:
1000 1000 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ...
output:
946 65 252 410 915 592 983 487 343 899 809 432 586 587 139 464 804 84 476 699 504 149 579 352 375 856 545 166 140 657 568 509 275 710 873 430 537 879 301 1 298 970 923 510 984 642 55 879 941 344 464 788 917 994 571 610 491 442 926 101 986 840 624 613 425 345 816 423 275 221 317 113 386 116 469 260 4...
result:
ok 1000 numbers
Test #6:
score: 0
Accepted
time: 1ms
memory: 5796kb
input:
1000 1000 1 -1000000000 1 -1000000000 1 -1000000000 1 -1000000000 1 -1000000000 1 -1000000000 1 -1000000000 1 -1000000000 1 -1000000000 1 -1000000000 1 -1000000000 1 -1000000000 1 -1000000000 1 -1000000000 1 -1000000000 1 -1000000000 1 -1000000000 1 -1000000000 1 -1000000000 1 -1000000000 1 -1000000...
output:
500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 ...
result:
ok 1000 numbers
Test #7:
score: -100
Wrong Answer
time: 2ms
memory: 7844kb
input:
1000 1000 -485078954 -474724347 -284958745 -99994191 -853392841 -796786314 -87134718 -861459498 -982809180 -184620712 -618476092 -244916830 -349486182 -751407510 -874417202 -419521829 -888338757 -735353446 -426330733 -715383449 -48093437 -359419189 -474876639 -887614191 -157085227 -51186523 -4851821...
output:
2 3 4 5 6 7 8 9 10 11 12 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 51 52 53 54 55 56 57 58 59 60 60 61 62 63 64 65 65 66 67 68 69 70 71 72 73 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 88 89 90 91 92 92 93 94 95 96...
result:
wrong answer 746th numbers differ - expected: '505', found: '506'