score and rank

S S S 为负比较简单,考虑每个数需不需要删,正确性很简单。

S S S 为正

我们从左往右遍历,假设遍历到了 i i i,我们就需要构造一个序列和原序列等价。

这里等价的意思是后缀和数组的最大值不变。

这里给出一种构造方法:

当加入一个正数,正常加入

当加入一个负数,考虑和前面抵消,如果前面的数不够减,那就全部舍弃。

例如

4 3 -5 2 2 2 2 2
-> 2 x x 2 2 2 2 2

容易发现,这两个序列是等价的。

#include <set>
#include <map>
#include <cmath>
#include <queue>
#include <stack>
#include <cstdio>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define fi first
#define se second
#define db double
#define LL long long
#define int long long
#define PII pair <int, int>
#define ULL unsigned long long
#define MP(x,y) make_pair (x, y)
#define rep(i,j,k) for (int i = (j); i <= (k); i++)
#define per(i,j,k) for (int i = (j); i >= (k); i--)

template <typename T>
void read (T &x) {
	x = 0; T f = 1; 
	char ch = getchar ();
	while (ch < '0' || ch > '9') {
		if (ch == '-') f = -1;
		ch = getchar ();
	}
	while (ch >= '0' && ch <= '9') {
		x = (x << 3) + (x << 1) + ch - '0';
		ch = getchar ();
	}
	x *= f;
}
template <typename T, typename... Args>
void read (T &x, Args&... Arg) {
	read (x), read (Arg...);
}
const int MaxPrint = 1000;
int Poi_For_Print, Tmp_For_Print[MaxPrint + 5];
template <typename T>
void write (T x) {
	if (x == 0) {
		putchar ('0');
		return;
	}
	bool flag = (x < 0 ? 1 : 0);
	x = (x < 0 ? -x : x);
	while (x) Tmp_For_Print[++Poi_For_Print] = x % 10, x /= 10;
	if (flag) putchar ('-');
	while (Poi_For_Print) putchar (Tmp_For_Print[Poi_For_Print--] + '0');
}
template <typename T, typename... Args>
void write (T x, Args... Arg) {
	write (x); putchar (' '); write (Arg...);
}
template <typename T, typename... Args>
void print (T x, char ch) {
	write (x); putchar (ch);
}
template <typename T> T Max (T x, T y) { return x > y ? x : y; }
template <typename T> T Min (T x, T y) { return x < y ? x : y; }
template <typename T> T Abs (T x) { return x > 0 ? x : -x; }

const int Maxn = 1e6;

int n, S;
int a[Maxn + 5];

signed main () {
//	freopen ("D:\\lihan\\1.in", "r", stdin);
	// freopen ("D:\\lihan\\1.out", "w", stdout);

	read (n, S);
	rep (i, 1, n) read (a[i]);

	if (S < 0) {
		int res = 0;
		rep (i, 1, n)
			if (a[i] > S)
				res++;
		write (res);
		return 0;
	}

	multiset <int> q;
	int Now = 0, ans = 0;
	rep (i, 1, n) {
		if (a[i] > 0) {
			q.insert (a[i]);
			Now += a[i];
			if (Now > S) {
				ans++;
				auto it = q.end (); it--;
				Now -= *it, q.erase (it);
			}
		}
		else {
			Now += a[i];
			if (Now < 0) {
				q.clear ();
				Now = 0;
				continue;
			}
			while (a[i]) {
				int x = *q.begin (); q.erase (q.begin ());
				if (a[i] + x > 0) {
					x += a[i];
					q.insert (x);
					break;
				}
				else {
					a[i] += x;
				}
			}
		}
	}
	write (ans);
	return 0;
}
posted @ 2022-09-11 16:18  C2022lihan  阅读(22)  评论(0编辑  收藏  举报