QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#449040 | #8526. Polygon II | ucup-team3215 | WA | 1ms | 3628kb | C++20 | 2.6kb | 2024-06-20 16:21:34 | 2024-06-20 16:21:34 |
Judging History
answer
#include <algorithm>
#include <cstdint>
#include <iostream>
#include <vector>
using namespace std;
constexpr int mod = 1e9 + 7, C = 3, N = 1e3 + 1;
using poly = vector<int>;
auto& mul(auto&& a, auto... b) { return ((a = a * (uint64_t)b % mod), ...); }
auto& add(auto&& a, auto... b) { return ((a -= (a += b) >= mod? mod: 0), ...); }
auto& adp(auto&& a, auto b, auto c) { return (a = (a + (uint64_t)b * c) % mod); }
auto& mad(auto&& a, auto b, auto c) { return (a = (a * (uint64_t)b + c) % mod); }
int inv_(int a) { for (int r = 1, b = mod - 2; ; mul(a, a), b /= 2) if (b % 2) mul(r, a); else if (!b) return r; }
poly dif(poly p, poly q) { if (p.size() < q.size()) p.resize(q.size()); for (int i = 0; i < q.size(); ++i) add(p[i], mod - q[i]); return p; }
int eval(const poly& p, int x) {
int res = 0;
for (int i = p.size(); i--; ) mad(res, x, p[i]);
return res;
}
int inv[N];
poly ade(poly p) {
for (int i = 0; i < p.size(); ++i) mul(p[i], inv[i + 1]);
p.insert(p.begin(), 0);
return p;
}
int main() {
cin.tie(0)->sync_with_stdio(0);
for (int i = 1; i < N; ++i) inv[i] = inv_(i);
int n; cin >> n;
int c0[C]{}, cnt[C]{};
for (int i = 0, x; i < n; ++i) cin >> x, ++c0[x], cnt[x - !!x] += !!x;
for (int i = C; --i; ) cnt[i - 1] += cnt[i];
vector<poly> cont{{1}, {0}};
for (int i = 1; i < n; ++i) {
vector<poly> nx;
poly pp;
for (int i = 0; auto& p: cont) p = ade(p), nx.push_back(dif(p, dif(pp, {eval(pp, 1)}))), pp = p;
nx.push_back({0});
cont = nx;
}
vector<int> e(n);
for (int i = 0; i < n; ++i) e[i] = add(eval(ade(cont[i]), 1), e[i - !!i]);
int ans = 0;
for (int c = C; c--; ) if (c0[c]) {
vector<int> dens{{1}}, ndens;
int64_t mins = 1 - (1ll << c), maxs = n - 2 + mins, L = 0;
for (int i = C; i--; ) maxs += 1ll * cnt[i] << i;
int cans = 0;
for (int i = C; i--; ) {
for (auto& x: dens) ndens.push_back(x), ndens.push_back(0);
swap(dens = {}, ndens);
dens.pop_back();
L *= 2;
for (int j = cnt[i]; j--; ) {
int64_t l = -(!j && i < c), r = j || i >= c;
dens.push_back(0);
for (int pp = 0; auto& p: dens) ndens.push_back(mul(pp + p, mod / 2 + 1)), pp = p;
maxs -= r << i, mins -= l << i;
L += l;
swap(dens = {}, ndens);
while (-L > maxs >> i) add(cans, dens[0]), dens.erase(dens.begin()), ++L;
while ((int)dens.size() + L - 1 > -mins >> i) dens.pop_back();
}
}
while (L <= 0) add(cans, mul(+dens[0], e[-L++])), dens.erase(dens.begin());
add(ans, mul(cans, c0[c]));
}
cout << add(1, mod - ans) << '\n';
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 1ms
memory: 3564kb
input:
3 0 2 0
output:
166666668
result:
ok 1 number(s): "166666668"
Test #2:
score: 0
Accepted
time: 0ms
memory: 3628kb
input:
3 0 0 0
output:
500000004
result:
ok 1 number(s): "500000004"
Test #3:
score: -100
Wrong Answer
time: 0ms
memory: 3628kb
input:
3 5 6 7
output:
1
result:
wrong answer 1st numbers differ - expected: '208333335', found: '1'