結果
問題 | No.603 hel__world (2) |
ユーザー | pekempey |
提出日時 | 2017-12-03 14:48:25 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 2,761 ms / 3,000 ms |
コード長 | 5,022 bytes |
コンパイル時間 | 2,277 ms |
コンパイル使用メモリ | 107,956 KB |
実行使用メモリ | 34,956 KB |
最終ジャッジ日時 | 2024-11-30 20:54:20 |
合計ジャッジ時間 | 11,199 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 36 ms
27,096 KB |
testcase_01 | AC | 36 ms
26,880 KB |
testcase_02 | AC | 38 ms
26,992 KB |
testcase_03 | AC | 41 ms
26,960 KB |
testcase_04 | AC | 43 ms
27,008 KB |
testcase_05 | AC | 40 ms
26,880 KB |
testcase_06 | AC | 34 ms
26,880 KB |
testcase_07 | AC | 49 ms
27,008 KB |
testcase_08 | AC | 35 ms
27,008 KB |
testcase_09 | AC | 36 ms
27,004 KB |
testcase_10 | AC | 43 ms
26,880 KB |
testcase_11 | AC | 86 ms
33,692 KB |
testcase_12 | AC | 72 ms
33,820 KB |
testcase_13 | AC | 87 ms
33,820 KB |
testcase_14 | AC | 46 ms
27,008 KB |
testcase_15 | AC | 36 ms
26,880 KB |
testcase_16 | AC | 38 ms
27,008 KB |
testcase_17 | AC | 38 ms
27,076 KB |
testcase_18 | AC | 37 ms
26,984 KB |
testcase_19 | AC | 35 ms
26,880 KB |
testcase_20 | AC | 2,760 ms
28,864 KB |
testcase_21 | AC | 2,761 ms
28,732 KB |
testcase_22 | AC | 34 ms
26,856 KB |
testcase_23 | AC | 69 ms
27,008 KB |
testcase_24 | AC | 76 ms
26,880 KB |
testcase_25 | AC | 255 ms
33,816 KB |
testcase_26 | AC | 248 ms
33,688 KB |
testcase_27 | AC | 252 ms
33,816 KB |
testcase_28 | AC | 74 ms
34,956 KB |
testcase_29 | AC | 64 ms
28,860 KB |
testcase_30 | AC | 52 ms
27,724 KB |
testcase_31 | AC | 35 ms
26,880 KB |
testcase_32 | AC | 61 ms
28,860 KB |
ソースコード
#pragma GCC optimize ("O3") #pragma GCC target ("avx") #include <iostream> #include <algorithm> #include <vector> #include <set> #include <string> #include <ctime> #include <map> using namespace std; typedef __int128 i128; const int N = 10; const int NN = 3; const int M = 180; const i128 B = 4 * i128(1e9) * i128(1e9); const long long mod = 1e6 + 3; long long fact[mod]; long long ifact[mod]; long long inv[mod]; long long modpow(long long a, long long b) { long long ret = 1; while (b > 0) { if (b & 1) ret = ret * a % mod; a = a * a % mod; b >>= 1; } return ret; } struct F { // base 10^20 // a[0] . a[1]a[2] ... a[N-1] i128 a[N]; i128 &operator[](int k) { return a[k]; } }; F operator+(F a, F b) { i128 c = 0; for (int i = N-1; i >= 0; i--) { a[i] += b[i] + c; if (a[i] > B) { a[i] -= B; c = 1; } else { c = 0; } } return a; } bool operator==(F a, F b) { for (int i = 0; i < N - NN; i++) { if (a[i] != b[i]) return false; } return true; } bool operator<(F a, F b) { for (int i = 0; i < N - NN; i++) { if (a[i] != b[i]) return a[i] < b[i]; } return false; } bool operator>(F a, F b) { for (int i = 0; i < N - NN; i++) { if (a[i] != b[i]) return a[i] > b[i]; } return false; } bool operator>=(F a, F b) { for (int i = 0; i < N - NN; i++) { if (a[i] != b[i]) return a[i] > b[i]; } return true; } F half(F a) { i128 c = 0; for (int i = 0; i < N; i++) { a[i] += c * B; c = a[i] % 2; a[i] /= 2; } return a; } F from_int(i128 n) { F a = {}; a[0] = n; return a; } F from_ratio(i128 a, i128 b) { F ret = {}; ret[0] = a; i128 c = 0; for (int i = 0; i < N; i++) { ret[i] += c * B; c = ret[i] % b; ret[i] /= b; } return ret; } void print(i128 a) { if (a == 0) { printf("0"); return; } char buf[100]; int ptr = 0; while (a > 0) { buf[ptr++] = a % 10 + '0'; a /= 10; } for (int i = ptr - 1; i >= 0; i--) { putchar(buf[i]); } } void print_fix(i128 a, int d) { char buf[100]; int ptr = 0; for (int i = 0; i < d; i++) { buf[ptr++] = a % 10 + '0'; a /= 10; } for (int i = ptr - 1; i >= 0; i--) { putchar(buf[i]); } } void show(F a) { print(a[0]); putchar('.'); for (int i = 1; i < 5; i++) { putchar(' '); print_fix(a[i], 27); } printf("\n"); } long long can_take(long long a, F b) { long long ok = 0; long long ng = 2e18; while (ng - ok > 1) { long long mid = (ok + ng) / 2; if (from_ratio(a + mid, mid) >= b) { ok = mid; } else { ng = mid; } } return ok; } long long C(int n, int r) { if (n < r) return 0; return fact[n] * ifact[r] % mod * ifact[n - r] % mod; } long long lucas(long long n, long long r) { if (n == 0 && r == 0) return 1; return C(n % mod, r % mod) * lucas(n / mod, r / mod) % mod; } int main() { fact[0] = 1; fact[1] = 1; ifact[0] = 1; ifact[1] = 1; inv[1] = 1; for (int i = 2; i < mod; i++) { fact[i] = fact[i - 1] * i % mod; inv[i] = inv[mod % i] * (mod - mod / i) % mod; ifact[i] = ifact[i - 1] * inv[i] % mod; } vector<long long> cnt(26); for (int i = 0; i < 26; i++) { cin >> cnt[i]; } string s; cin >> s; vector<int> sum(26); for (char c : s) { sum[c - 'a']++; } for (int i = 0; i < 26; i++) { if (sum[i] > cnt[i]) { cout << 0 << endl; return 0; } cnt[i] -= sum[i]; } vector<vector<int>> g(26); int i = 0; while (i < s.size()) { int j = i; while (i < s.size() && s[i] == s[j]) { i++; } g[s[j] - 'a'].push_back(i - j); } long long ans = 1; for (int iii = 0; iii < 26; iii++) { auto x = g[iii]; long long C = cnt[iii]; F ok = from_int(1); F ng = from_int(2e18); if (C == 0) continue; clock_t beg = clock(); map<int, int> xs; for (int e : x) xs[e]++; for (int ii = 0; ii < M; ii++) { F mid = half(ok + ng); // x[0]/1 (x[0]+1)/2 (x[0]+2)/3 ... // (x + k) / k >= mid i128 t = 0; for (auto kv : xs) { t += can_take(kv.first, mid) * kv.second; } if (t >= C) { ok = mid; } else { ng = mid; } } struct Foo { int x; long long take; long long cnt; }; vector<Foo> take, take2; for (auto kv : xs) { long long t = can_take(kv.first, ng); take.push_back({kv.first, t, kv.second}); C -= t * kv.second; } for (Foo foo : take) { if (can_take(foo.x, ok) > can_take(foo.x, ng)) { long long canuse = min(C, foo.cnt); Foo bar = foo; foo.take++; foo.cnt = canuse; bar.cnt -= canuse; take2.push_back(foo); take2.push_back(bar); C -= canuse; } else { take2.push_back(foo); } } for (Foo foo : take2) { ans *= modpow(lucas(foo.x + foo.take, foo.take), foo.cnt); ans %= mod; } } cout << ans << endl; }