結果
| 問題 |
No.563 超高速一人かるた large
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2017-08-26 01:13:18 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 1,944 ms / 3,000 ms |
| コード長 | 2,463 bytes |
| コンパイル時間 | 1,630 ms |
| コンパイル使用メモリ | 98,188 KB |
| 最終ジャッジ日時 | 2025-01-05 02:32:06 |
|
ジャッジサーバーID (参考情報) |
judge3 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 18 |
コンパイルメッセージ
main.cpp: In function ‘int main()’:
main.cpp:42:29: warning: iteration 200009 invokes undefined behavior [-Waggressive-loop-optimizations]
42 | fact[i] = i * fact[i - 1];
| ^
main.cpp:41:21: note: within this loop
41 | for (int i = 1; i <= N; i++) {
| ~~^~~~
main.cpp:46:43: warning: iteration 200008 invokes undefined behavior [-Waggressive-loop-optimizations]
46 | inv[i] = inv[mod % i] * (mod - mod / i);
| ^
main.cpp:45:21: note: within this loop
45 | for (int i = 2; i <= N; i++) {
| ~~^~~~
cc1plus: warning: iteration 200009 invokes undefined behavior [-Waggressive-loop-optimizations]
main.cpp:49:21: note: within this loop
49 | for (int i = 1; i <= N; i++) {
| ~~^~~~
ソースコード
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
using namespace std;
constexpr int mod = 1e9 + 7;
struct modint {
int n;
modint(int n = 0) : n(n) {}
};
modint operator+(modint a, modint b) { return modint((a.n += b.n) >= mod ? a.n - mod : a.n); }
modint operator-(modint a, modint b) { return modint((a.n -= b.n) < 0 ? a.n + mod : a.n); }
modint operator*(modint a, modint b) { return modint(1LL * a.n * b.n % mod); }
modint &operator+=(modint &a, modint b) { return a = a + b; }
modint &operator-=(modint &a, modint b) { return a = a - b; }
modint &operator*=(modint &a, modint b) { return a = a * b; }
constexpr int N = 2e5 + 10;
modint fact[N];
modint ifact[N];
modint inv[N];
modint P(int n, int r) {
if (n < 0 || r < 0 || n < r) return 0;
return fact[n] * ifact[n - r];
}
modint C(int n, int r) {
if (n < 0 || r < 0 || n < r) return 0;
return fact[n] * ifact[r] * ifact[n - r];
}
int main() {
fact[0] = 1;
for (int i = 1; i <= N; i++) {
fact[i] = i * fact[i - 1];
}
inv[1] = 1;
for (int i = 2; i <= N; i++) {
inv[i] = inv[mod % i] * (mod - mod / i);
}
ifact[0] = 1;
for (int i = 1; i <= N; i++) {
ifact[i] = inv[i] * ifact[i - 1];
}
int n;
cin >> n;
vector<string> s(n);
for (int i = 0; i < n; i++) {
cin >> s[i];
}
sort(s.begin(), s.end());
vector<int> h(n - 1);
for (int i = 0; i + 1 < n; i++) {
int k = 0;
while (k < s[i].size() && k < s[i + 1].size() && s[i][k] == s[i + 1][k]) k++;
h[i] = k;
}
vector<modint> ans(n + 2);
for (int i = 0; i < n; i++) {
vector<int> lcp(n);
int k = s[i].size();
for (int j = i + 1; j < n; j++) {
k = min(k, h[j - 1]);
lcp[j] = k;
}
k = s[i].size();
for (int j = i - 1; j >= 0; j--) {
k = min(k, h[j]);
lcp[j] = k;
}
map<int, int> mp;
for (int j = 0; j < n; j++) {
if (i != j) mp[-lcp[j]]++;
}
int c = 0;
for (auto kv : mp) {
for (int j = 1; j <= n; j++) {
int x = c;
int y = c + kv.second;
ans[j] -= -(kv.first - 1) * P(j - 1, y) * P(n - 1 - y, j - 1 - y);
ans[j] += -(kv.first - 1) * P(j - 1, x) * P(n - 1 - x, j - 1 - x);
}
c += kv.second;
// ans[c] += -kv.first * fact[c - 1] * fact[n - c];
}
}
for (int i = 1; i <= n; i++) {
ans[i] += ans[i - 1] * (n - i + 1);
if (i == n) ans[i] += fact[n];
cout << ans[i].n << endl;
}
}