結果
問題 | No.603 hel__world (2) |
ユーザー |
![]() |
提出日時 | 2017-12-01 00:41:35 |
言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 120 ms / 3,000 ms |
コード長 | 4,010 bytes |
コンパイル時間 | 1,920 ms |
コンパイル使用メモリ | 177,688 KB |
実行使用メモリ | 31,608 KB |
最終ジャッジ日時 | 2024-11-30 20:53:16 |
合計ジャッジ時間 | 4,503 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 30 |
ソースコード
#include<bits/stdc++.h>using namespace std;const int M = 1000003;const int IINF = 1000000007;const long long LINF = (long long)3e18;const double eps = 1e-16;using frac = pair<long long, long long>;long long fact[1000003], inv[1000003];inline long long powmod(long long a, long long b) {if (b == 0) return 1LL;return (b & 1) ? a * powmod(a, b - 1) % M : powmod(a * a % M, b / 2);}inline long long comb(long long n, int k) {int a = (int)(n % M);int b = (int)((n - k) % M);if (a <= b) return 0;return fact[a] * inv[k] % M * inv[b] % M;}// a < b : -1, a == b : 0, a > b : 1inline int compare(frac a, frac b) {double dda = b.second / (double)b.first;double ddb = a.second / (double)a.first;if (dda < ddb - eps) return -1;if (ddb < dda - eps) return 1;dda = a.first / (double)a.second;ddb = b.first / (double)b.second;if (dda < ddb - eps) return -1;if (ddb < dda - eps) return 1;long long da = a.first / a.second;long long db = b.first / b.second;if (da < db) return -1;if (da > db) return 1;a.first -= da * a.second;b.first -= db * b.second;if (a.first == 0 && b.first == 0) return 0;if (a.first == 0) return -1;if (b.first == 0) return 1;if (a.second < IINF && b.second < IINF) {long long ma = a.first * b.second;long long mb = b.first * a.second;return ma < mb ? -1 : ma == mb ? 0 : -1;}return compare(frac(b.second, b.first), frac(a.second, a.first));}inline frac getmin(frac& a, frac& b) {return compare(a, b) < 0 ? a : b;}int main() {fact[0] = 1;for (int i = 1; i < M; ++i)fact[i] = fact[i - 1] * i % M;inv[M - 1] = powmod(fact[M - 1], M - 2);for (int i = M - 1; i > 0; --i)inv[i - 1] = inv[i] * i % M;long long s[26];for (int i = 0; i < 26; ++i)cin >> s[i];string t;cin >> t;vector<int> lis[26];int sz[26] = {};for (int i = 0; i < (int)t.size(); ++i) {if (i > 0 && t[i] == t[i - 1])++lis[t[i] - 'a'][sz[t[i] - 'a'] - 1];else {lis[t[i] - 'a'].push_back(1);++sz[t[i] - 'a'];}--s[t[i] - 'a'];}long long ans = 1;for (int i = 0; i < 26; ++i) {if (s[i] < 0) {cout << "0\n";return 0;}if (s[i] == 0 || sz[i] == 0) continue;int sm = 0;for (int j : lis[i])sm += j;long double l = sm / ((long double)s[i] + sz[i] + eps), r = sm / ((long double)s[i] - eps);vector<long long> cnt(sz[i]);while (1) {long double m = (l + r) / 2;long long sum = 0;vector<int> minid;int minc = 0;frac minf = frac(IINF, 1);for (int j = 0; j < sz[i]; ++j) {if (sum + lis[i][j] / m - 1 > LINF) {sum = LINF;break;}cnt[j] = (long long)(lis[i][j] / m + eps);if (cnt[j] == 0) continue;frac f = frac(lis[i][j], cnt[j]);int c = compare(minf, f);if (c == 0) {++minc;minid.push_back(j);}else if (c > 0) {minf = f;minid.clear();minc = 1;minid.push_back(j);}sum += cnt[j];}if (sum >= s[i] && sum - minc <= s[i]) {int d = sum - s[i];for (int j = 0; j < d; ++j)--cnt[minid[j]];break;}if (sum < s[i])r = m;elsel = m;}for (int j = 0; j < sz[i]; ++j)ans = ans * comb(lis[i][j] + cnt[j], lis[i][j]) % M;}cout << ans << "\n";return 0;}