QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#133781#4939. Red Black BallTeam_name#WA 1ms19988kbC++203.2kb2023-08-02 13:59:582023-08-02 14:00:04

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-08-02 14:00:04]
  • 评测
  • 测评结果:WA
  • 用时:1ms
  • 内存:19988kb
  • [2023-08-02 13:59:58]
  • 提交

answer

#include <bits/stdc++.h>

#define _debugVar(x) { cerr << #x << " = " << x << endl; }

using namespace std;
using LL = long long;

const int N = 128;
constexpr LL P = 998244353;
const int INF = 0x3f3f3f3f;
const int Base = 50;

LL power(LL x, LL k)
{
	LL res = 1;
	while(k) {
		if(k&1) res = res*x%P;
		x = x*x%P; k >>= 1;
	}
	return res%P;
}
LL inv(LL x) { return power(x, P-2); }

int n, m;
struct Ball
{
	int pos;
	int color;// RED 0, BLACK 1
}a[N];

bool cmp(Ball a, Ball b) { return a.pos < b.pos; }

int b[N];

LL fact[N];

LL f[N][N][N]; // f[i][j][k] 表示 (i, j) 选 [红, 黑] 的 红 - 黑 = k 的方案数

vector<int> v;

LL dp(int l, int r, int k)
{
	if(l+1 == r) return (LL)(k == 0);
	LL &res = f[l][r][k+Base];
	if(res != -1) return res;
	res = 0;
	for(int i = l+1; i < r; i++) {
		if(v[i]-v[l] <= v[r]-v[i]) { // RED
			res += dp(i, r, k-(i-l))*fact[r-l-2]%P*inv(fact[i-l-1])%P*inv(fact[r-i-1])%P;
			res %= P;
		} else { // BLACK
			res += dp(l, i, k-(r-i))*fact[r-l-2]%P*inv(fact[i-l-1])%P*inv(fact[r-i-1])%P;
			res %= P;
		}
	}
	return res;
}


LL g[N][N]; // 第 i 个区间的方案数
LL c[N];
int cnt_g = 0; 

void count(int l, int r)
{
	_debugVar(l); _debugVar(r);
	cnt_g++;
	int left_col = -1, right_col = -1;
	for(int i = 1; i <= n; i++) {
		if(a[i].pos == l) left_col = a[i].color;
		if(a[i].pos == r) right_col = a[i].color;
	}
	
	v.clear();
	
	for(int i = 1; i <= m; i++) {
		if(l <= b[i] && b[i] <= r) {
			v.push_back(b[i]);
		}
	}
	int nums = v.size();
	_debugVar(nums);

	if(left_col == -1 || right_col == -1 || left_col == right_col) {
		int col = left_col;
		if(col == -1) col = right_col;

		if(col == 0) {
			g[cnt_g][Base+nums] = fact[nums];
		} else {
			g[cnt_g][Base-nums] = fact[nums];
		}
		return;
	} 

	v.push_back(l); v.push_back(r);
	sort(v.begin(), v.end());

	memset(f, -1, sizeof f);
	// 左右颜色不同了	
	int sign = 1;
	if(left_col == 1) sign = -1;
	for(int i = -nums; i <= nums; i++) {
		g[cnt_g][i*sign+Base] = dp(0, v.size()-1, i);
		_debugVar(dp(0, v.size()-1, i));
	}
	c[cnt_g] = nums;
}

LL h[N][N];

int main()
{
	// freopen("1.in", "r", stdin);
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	fact[0] = 1;
	for(int i = 1; i < N; i++) 
		fact[i] = fact[i-1]*i%P;

	cin >> n >> m;
	for(int i = 1; i <= n; i++) {
		string str;
		cin >> a[i].pos >> str;
		if(str == "BLACK") a[i].color = 1;
		else a[i].color = 0;
	}

	for(int i = 1; i <= m; i++) 
		cin >> b[i];
	sort(a+1, a+n+1, cmp);

	for(int i = 1; i <= n; i++) {
		 count(a[i-1].pos, a[i].pos);
	}
	count(a[n].pos, INF);

	LL ab = fact[m];
	for(int i = 1; i <= cnt_g; i++) 
		ab = ab*inv(fact[c[i]])%P;
	_debugVar(c[2]);
	_debugVar(cnt_g);
	_debugVar(ab);

	memset(h, 0, sizeof h);
	h[0][Base] = 1;
	for(int i = 1; i <= n; i++) {
		for(int j = 0; j <= 2*Base; j++) {
			for(int k = 0; k <= 2*Base; k++) {
				// _debugVar(g[i][k]);
				if(j >= (k-Base)) {
					h[i][j] += h[i-1][j-(k-Base)]*g[i][k]%P;
					h[i][j] %= P;
				}
			}
		}
	}
	LL ans = 0;
	for(int i = Base+1; i <= 2*Base; i++) {
		ans += h[cnt_g][i];
		ans %= P;
	}
	ans = ans*ab%P;
	cout << ans << endl;
	return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 0
Wrong Answer
time: 1ms
memory: 19988kb

input:

2 3
1 BLACK
10 RED
2 5 7

output:

0

result:

wrong answer 1st lines differ - expected: '3', found: '0'