結果
問題 | No.603 hel__world (2) |
ユーザー | pekempey |
提出日時 | 2017-12-03 14:37:13 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
TLE
|
実行時間 | - |
コード長 | 4,821 bytes |
コンパイル時間 | 1,467 ms |
コンパイル使用メモリ | 102,428 KB |
実行使用メモリ | 33,964 KB |
最終ジャッジ日時 | 2024-05-06 06:27:21 |
合計ジャッジ時間 | 6,943 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge5 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 43 ms
33,964 KB |
testcase_01 | AC | 46 ms
26,880 KB |
testcase_02 | AC | 44 ms
26,960 KB |
testcase_03 | AC | 55 ms
27,008 KB |
testcase_04 | AC | 65 ms
26,880 KB |
testcase_05 | AC | 58 ms
26,936 KB |
testcase_06 | AC | 31 ms
26,876 KB |
testcase_07 | AC | 88 ms
26,916 KB |
testcase_08 | AC | 37 ms
26,856 KB |
testcase_09 | AC | 37 ms
26,880 KB |
testcase_10 | AC | 65 ms
26,880 KB |
testcase_11 | TLE | - |
testcase_12 | -- | - |
testcase_13 | -- | - |
testcase_14 | -- | - |
testcase_15 | -- | - |
testcase_16 | -- | - |
testcase_17 | -- | - |
testcase_18 | -- | - |
testcase_19 | -- | - |
testcase_20 | -- | - |
testcase_21 | -- | - |
testcase_22 | -- | - |
testcase_23 | -- | - |
testcase_24 | -- | - |
testcase_25 | -- | - |
testcase_26 | -- | - |
testcase_27 | -- | - |
testcase_28 | -- | - |
testcase_29 | -- | - |
testcase_30 | -- | - |
testcase_31 | -- | - |
testcase_32 | -- | - |
ソースコード
#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 = 20; const int NN = 5; const int M = 200; 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]; 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; } } // fprintf(stderr, "%.4f\n", (double)(clock() - beg) / CLOCKS_PER_SEC); vector<long long> take(x.size()); for (int i = 0; i < x.size(); i++) { take[i] = can_take(x[i], ng); C -= take[i]; } for (int i = 0; i < x.size(); i++) { if (C > 0 && can_take(x[i], ok) > can_take(x[i], ng)) { take[i]++; C--; } } #ifdef FOO cout << x.size() << endl; cout << C << endl; #endif for (int i = 0; i < x.size(); i++) { #ifdef FOO cout << i << ' ' << x[i] << ' ' << take[i] << ' ' << lucas(x[i] + take[i], take[i]) << endl; #endif ans *= lucas(x[i] + take[i], take[i]); ans %= mod; } #ifdef FOO cerr << "ok "; show(ok); #endif } cout << ans << endl; }