[ABC321F] #(subset sum = K) with Add and Erase

这不可撤销背包板子吗。

fif_i 表示凑出 ii 方案数。

加的时候加一下,删的时候减一下,注意两个循环顺序不一样,具体可以看代码理解。

#include <bits/stdc++.h>
using namespace std;
#define int long long

const int N = 5e5 + 5, MOD = 998244353; // Remember to change

int n, k, q, t, a[N];
int dp[N];

namespace FastIo
{
	#define QUICKCIN ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
	int read()
	{
		char ch = getchar();
		int x = 0, f = 1;
		while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
		while (ch == '-')
		{
			f = -f;
			ch = getchar();
		}
		while (ch >= '0' && ch <= '9')
		{
			x = (x << 1) + (x << 3) + (ch ^ 48);
			ch = getchar();
		}
		return x * f;
	}
	template<class T>
	void write(T x)
	{
		if (x < 0)
		{
			putchar('-');
			x = -x;
		}
		if (x > 9) write(x / 10);
		putchar(x % 10 + '0');
	}
	template<class T>
	void writeln(T x)
	{
		write(x);
		putchar('\n');
	}
}

signed main()
{
	ios::sync_with_stdio(0), cin.tie(0);
	set<int> v;
	cin >> t >> k;
	dp[0] = 1;
	while (t--)
	{
		char op;
		cin >> op;
		if (op == '+')
		{
			int x;
			cin >> x;
			v.insert(x);
			for (int i = k; i >= x; i--)
			{
				dp[i] += dp[i - x];
				dp[i] %= MOD;
			}
		}
		else
		{
			int x;
			cin >> x;
			v.erase(x);
			for (int i = x; i <= k; i++)
			{
				dp[i] -= dp[i - x];
				dp[i] %= MOD;
				dp[i] += MOD;
				dp[i] %= MOD;
			}
		}
		cout << dp[k] << "\n";
	}
	return 0;
}
posted @ 2023-09-24 08:44  HappyBobb  阅读(22)  评论(0)    收藏  举报  来源