QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#462764 | #7087. Counting Polygons | teraqqq | WA | 387ms | 237912kb | C++14 | 4.1kb | 2024-07-04 03:15:03 | 2024-07-04 03:15:05 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
constexpr int MOD = 1'000'000'007;
constexpr int N = 10'000'228;
constexpr int M = 2*N;
int minp[N+1], fact[M+1], rfct[M+1], phi[N+1];
int rev(int a, int m = MOD) {
return a == 1 ? 1 : m - (ll)m*rev(m%a,a)/a;
}
int c(int n, int k) {
return 0 <= k && k <= n ? (ll)fact[n]*rfct[k]%MOD*rfct[n-k]%MOD : 0;
}
void mod_add(int& a, int b) {
a += b;
if (a >= MOD) a -= b;
}
void mod_sub(int& a, int b) {
a -= b;
if (a < 0) a += MOD;
}
int cnt(int n, int mp, int sn) {
if (n < 0) return 0;
if (sn) {
int a = cnt(n, mp+1, sn-1);
mod_add(a, cnt(n+1, mp+1, sn-1));
return a;
} else {
const int a = n%2 ? 0 : c(n/2-1, mp-1);
return a;
}
}
int solve(int n, int m) {
vector<int> divs{{1}};
for (int j = m; j != 1; ) {
const int p = minp[j], s = divs.size();
// cout << j << ", p=" << p << endl;
int k = 0;
while (j % p == 0) j /= p, ++k;
for (int i = 0; i < s*k; ++i)
divs.push_back(divs[i]*p);
}
int ans = 0;
for (int d : divs) {
if (d == m) {
mod_add(ans, c(n-1, m-1));
ans = (ans + (ll)(MOD - m)*c(n/2, m-1))%MOD;
// cout << "d=" << d << ": " << ans << " " << 1 << endl;
} else {
const int cnt = m / d;
if (n % cnt == 0)
ans = (ans + (ll)c(n/cnt-1, d-1)*phi[cnt])%MOD;
// cout << "d=" << d << ": " << ans << " " << phi[cnt] << endl;
}
}
// cerr << ans << " half" << endl;
if (m % 2) {
ans = (ans + (ll)m*cnt(n, m/2, 1))%MOD;
ans = (ans + (ll)(MOD-m)*cnt(n/2+1, m/2, 1))%MOD;
} else {
ans = (ans + (ll)(m/2)*cnt(n, m/2, 0))%MOD;
ans = (ans + (ll)(m/2)*cnt(n, m/2-1, 2))%MOD;
ans = (ans + (ll)(MOD-m)*cnt(n/2+1, m/2-1, 2))%MOD;
}
// cerr << ans << "!" << endl;
ans = (ll)ans*rev(2*m)%MOD;
if (ans < 0) ans += MOD;
return ans;
}
int solve_brute(int n, int m, int max, vector<int>& st) {
if (n < m) return 0;
if (!m) {
if (n != 0) return 0;
auto v = st;
for (int t = 2; t--; ) {
reverse(v.begin(), v.end());
for (int i = 0; i < st.size(); ++i) {
rotate(v.begin(), v.begin()+1, v.end());
if (v < st) return 0;
}
}
// for (int x : st) cout << x << ' ';
// cout << endl;
return 1;
}
int ans = 0;
st.push_back(0);
for (int x = 1; x <= n && 2*x < max; ++x) {
st.back() = x;
ans += solve_brute(n-x, m-1, max, st);
}
st.pop_back();
return ans;
}
int solve_brute(int n, int m) {
vector<int> st;
int ans = solve_brute(n, m, n, st);
return ans;
}
int main() {
ios::sync_with_stdio(0); cin.tie(0);
for (int i = 2; i <= N; ++i) {
if (minp[i]) continue;
minp[i] = i;
if ((ll)i*i > N) continue;
for (int j = i*i; j <= N; j += i)
if (!minp[j]) minp[j] = i;
}
phi[1] = 1;
for (int i = 2; i <= N; ++i) {
const int p = minp[i];
const int j = i / p;
if (p == minp[j]) phi[i] = phi[j] * p;
else phi[i] = phi[j] * (p-1);
}
fact[0] = 1;
for (int i = 1; i <= M; ++i) fact[i] = (ll)fact[i-1]*i%MOD;
rfct[M] = rev(fact[M]);
for (int i = M; i >= 1; --i) rfct[i-1] = (ll)rfct[i]*i%MOD;
for (int n = 1; n <= 20; ++n) {
// cerr << "m=" << m << endl;
for (int m = 3; m <= n; ++m) {
int pans = solve(n, m);
int jans = solve_brute(n, m);
if (pans != jans) {
cout << "WA!" << endl;
cout << n << " " << m << endl;
cout << "pans=" << pans << endl;
cout << "jans=" << jans << endl;
exit(0);
}
}
}
int t; cin >> t;
while (t--) {
int n, m; cin >> n >> m;
int ans = solve(n, m);
cout << ans << '\n';
}
}
详细
Test #1:
score: 100
Accepted
time: 360ms
memory: 237912kb
input:
4 3 3 4 3 5 3 7 4
output:
1 0 1 3
result:
ok 4 tokens
Test #2:
score: -100
Wrong Answer
time: 387ms
memory: 237872kb
input:
10000 8708700 6531525 8062080 4031040 7068600 2356200 3659040 332640 7309575 2088450 5503680 1572480 7162848 3581424 9831360 7724640 6306300 5045040 5783400 2891700 4677120 2338560 5110560 786240 9525600 2381400 6955200 4173120 8229375 3291750 7068600 5405400 9639000 3213000 5969040 2984520 5274360 ...
output:
45666775 386843180 867437616 253300932 482697442 649018062 157961376 79708753 910840671 748709468 762771581 839851514 132357899 326189264 36752374 993212465 73044078 493706137 506234162 982243306 632144614 295169771 380670445 257151958 690742488 609943733 903896971 483810853 402932842 865811879 3675...
result:
wrong answer 1st words differ - expected: '70575804', found: '45666775'