QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#692780#6132. Repair the ArtworkOIer_kzcTL 3ms4596kbC++173.0kb2024-10-31 15:01:502024-10-31 15:01:51

Judging History

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

  • [2024-10-31 15:01:51]
  • 评测
  • 测评结果:TL
  • 用时:3ms
  • 内存:4596kb
  • [2024-10-31 15:01:50]
  • 提交

answer

#include <stdio.h>
#include <string.h>
#include <assert.h>

#include <vector>
#include <algorithm>

#define eb emplace_back

#define LOG(FMT...) fprintf(stderr, FMT)

using namespace std;

typedef long long LL;
constexpr int N = 105, mod = (int)1e9 + 7;

constexpr int reduce(int x) {
	return x >= mod ? x - mod : x;
}

constexpr int neg(int x) {
	return x ? mod - x : 0;
}

void Add(int &x, int y) {
	if ((x += y) >= mod) {
		x -= mod;
	}
}

constexpr int inv(int x, int k = mod - 2) {
	int r = 1;
	while (k) {
		if (k & 1) {
			r = x * (LL)r % mod;
		}
		x = x * (LL)x % mod;
		k >>= 1;
	}
	return r;
}

struct Pair {
	int x, y;
	Pair() {}
	Pair(int _x, int _y) : x(_x), y(_y) {}
	bool operator < (const Pair &t) const {
		return y < t.y;
	}
};
struct Poly {
	vector<Pair> v;
	Poly() : v{Pair(1, 0)} {}
	Poly(int k) : v{Pair(1, k * (k + 1) / 2)} {}
	Poly(vector<Pair> &t) : v(t) {}
	Pair &operator[] (int k) {
		return v[k];
	}
	Pair operator[] (int k) const {
		return v[k];
	}
	int size() const {
		return (int)v.size();
	}
	Poly operator * (const Poly &t) const {
		vector<Pair> ret;
		for (int i = 0; i < v.size(); ++i) {
			for (int j = 0; j < t.size(); ++j) {
				ret.eb(v[i].x * (LL)t[j].x % mod, reduce(v[i].y + t[j].y));
			}
		}
		return ret;
	}
	Poly operator - (const Poly &t) const {
		vector<Pair> ret(v.size() + t.size());
		for (int i = 0; i < v.size(); ++i) {
			ret[i] = v[i];
		}
		for (int i = 0; i < t.size(); ++i) {
			auto &[x, y] = ret[i + v.size()];
			x = neg(t[i].x), y = t[i].y;
		}
		sort(ret.begin(), ret.end());
		int k = 0;
		for (int i = 0, j; (j = i) < ret.size(); i = j) {
			int coef = 0;
			while (j < ret.size() && ret[i].y == ret[j].y) {
				Add(coef, ret[j].x);
				++j;
			}
			ret[k++] = Pair(coef, ret[i].y);
		}
		ret.erase(ret.begin() + k, ret.end());
		return ret;
	}
	int val(int k) const {
		int ret = 0;
		for (const auto &[x, y] : v) {
			ret = (ret + x * (LL)inv(y, k)) % mod;
		}
		return ret;
	}
};

int a[N], n, m;
bool was[N][N];
Poly f[N][N];

Poly dp(int l, int r) {
	if (l == r + 1) {
		return Poly();
	}
	if (was[l][r]) {
		return f[l][r];
	}
	was[l][r] = true;
	Poly &ret = f[l][r];
	ret = Poly(r - l + 1);
	for (int k = l; k <= r; ++k) {
		if (a[k] == 1) {
			LOG("ERR\n");
			while (true);
		}
		if (a[k] == 2) {
			ret = ret - dp(l, k - 1) * Poly(r - k);
		}
	}
	return ret;
}

void solve() {
	memset(was, 0, sizeof was);
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; ++i) {
		scanf("%d", a + i);
	}
	Poly ret;
	for (int i = 1, j; (j = i) <= n; i = j + 1) {
		while (j <= n && a[j] != 1) {
			j += 1;
		}
		if (a[i] != 1) {
			ret = ret * dp(i, j - 1);
		}
	}
	int res = ret.val(m);
	/* LOG("%d\n", ret.size());
	for (auto [x, y] : ret.v) LOG("%d %d\n", x, y); */
	/* for (int i = 1; i <= m; ++i) {
		res = res * (LL)i % mod;
	} */
	printf("%d\n", res);
}

int main() {
	int task;
	for (scanf("%d", &task); task--; ) {
		solve();
	}
	return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 1ms
memory: 4416kb

input:

3
2 2
2 0
3 2
2 1 0
3 1
2 1 0

output:

8
3
1

result:

ok 3 number(s): "8 3 1"

Test #2:

score: 0
Accepted
time: 3ms
memory: 4596kb

input:

100
2 1
0 1
2 1
2 1
2 1
1 1
1 6
2
1 14
2
3 12
2 2 2
6 13
2 2 0 2 0 2
7 14
0 0 0 0 2 2 0
5 8
2 2 0 0 0
5 5
2 2 0 0 0
12 3
0 2 0 2 2 0 1 2 2 2 2 0
7 11
2 2 0 1 0 1 0
4 4
2 1 2 2
7 5
1 1 0 0 1 0 0
2 14
2 1
15 17
2 2 1 2 0 0 0 0 2 0 1 0 0 0 0
15 11
1 1 2 0 1 2 0 0 1 0 2 1 1 1 1
15 18
1 0 1 0 2 2 1 2 0 1...

output:

1
1
0
1
1
175715347
833406719
467966815
458805426
650344
2208
537089254
146
7776
1
703335050
123067364
355668256
487954758
53774922
544070885
436748805
369291507
760487845
513270785
501075264
487417783
464534262
979007529
137956839
143317512
648268264
851188473
702545117
946416372
595191705
35054850...

result:

ok 100 numbers

Test #3:

score: -100
Time Limit Exceeded

input:

1000
20 673037423
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
3 774964932
2 2 2
17 730319736
2 2 1 1 2 2 2 2 2 2 2 2 2 1 2 2 1
11 893285699
2 2 2 1 2 1 2 2 2 1 2
16 98149251
1 2 1 2 1 2 1 1 2 1 2 2 2 2 1 2
7 556953277
1 2 2 1 2 2 2
3 228111342
1 1 1
11 640995044
2 2 1 1 2 2 1 1 1 1 1
19 741419324
1 1 2 ...

output:


result: