結果

問題 No.295 hel__world
ユーザー Min_25
提出日時 2017-05-04 21:59:00
言語 C++14
(gcc 13.3.0 + boost 1.87.0)
結果
AC  
実行時間 550 ms / 5,000 ms
コード長 3,248 bytes
コンパイル時間 1,230 ms
コンパイル使用メモリ 106,368 KB
実行使用メモリ 10,788 KB
最終ジャッジ日時 2024-09-14 07:16:50
合計ジャッジ時間 5,592 ms
ジャッジサーバーID
(参考情報)
judge2 / judge3
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 4
other AC * 53
権限があれば一括ダウンロードができます

ソースコード

diff #
プレゼンテーションモードにする

#include <cstdio>
#include <cassert>
#include <cmath>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <functional>
#include <stack>
#include <queue>
#include <tuple>
#define getchar getchar_unlocked
#define putchar putchar_unlocked
#define _rep(_1, _2, _3, _4, name, ...) name
#define rep2(i, n) rep3(i, 0, n)
#define rep3(i, a, b) rep4(i, a, b, 1)
#define rep4(i, a, b, c) for (int i = int(a); i < int(b); i += int(c))
#define rep(...) _rep(__VA_ARGS__, rep4, rep3, rep2, _)(__VA_ARGS__)
using namespace std;
using i64 = long long;
using u32 = unsigned;
using u64 = unsigned long long;
using f80 = long double;
using i128 = __int128_t;
void solve() {
const i64 lim = i64(1) << 62;
i64 counts[26];
static char str[1000010];
while (~scanf("%lld", &counts[0])) {
rep(i, 1, 26) scanf("%lld", &counts[i]);
scanf("%s", str);
const int slen = strlen(str);
rep(i, slen) str[i] -= 'a';
vector<int> lens[26];
int freqs[26] = {};
{
int i = 0;
for (int j; i < slen; i = j) {
int c = str[i]; j = i + 1;
while (j < slen && str[j] == c) ++j;
lens[c].push_back(j - i);
freqs[c] += j - i;
}
}
struct Fraction {
Fraction() {}
Fraction(int n, int d) : n(n), d(d) {}
bool operator < (const Fraction& rhs) const {
return i64(n) * rhs.d < i64(d) * rhs.n;
}
int n, d;
};
i128 ans = 1;
rep(i, 26) {
if (freqs[i] > counts[i]) {
ans = 0; break;
}
}
if (ans > 0) rep(i, 26) {
if (freqs[i] == 0) continue;
i64 rest = counts[i] - freqs[i];
auto binom = [&] (i64 n, int k) {
double prod = 1;
rep(i, k) {
prod = prod * (n - k + i + 1) / (i + 1);
if (prod >= lim * 1.01) return i128(lim);
}
i128 ret = 1;
rep(i, k) {
ret = ret * (n - i) / (i + 1);
}
return min(ret, i128(lim));
};
sort(lens[i].begin(), lens[i].end());
bool brute = false;
i128 prod = 1;
if (lens[i].size() <= 2) {
if (lens[i].size() == 1) {
prod = binom(counts[i], lens[i][0]);
} else {
if (lens[i][1] == 1) {
prod = i128(counts[i] / 2) * (counts[i] - counts[i] / 2);
} else brute = true;
}
} else brute = true;
if (brute) {
using P = pair<int, int>;
priority_queue< pair<Fraction, P> > que;
rep(id, lens[i].size()) {
que.push({{lens[i][id] + 1, 1}, {id, 1}});
}
for (; rest; --rest) {
auto d = que.top(); que.pop();
auto f = d.first;
int id, j; tie(id, j) = d.second;
prod = prod * f.n / f.d;
if (prod >= lim) break;
auto nf = Fraction(lens[i][id] + j + 1, j + 1);
que.push({nf, {id, j + 1}});
}
}
if (prod >= lim || (ans *= prod) >= lim) {
ans = lim; break;
}
}
if (ans >= lim) puts("hel");
else printf("%lld\n", i64(ans));
}
}
int main() {
auto beg = clock();
solve();
auto end = clock();
fprintf(stderr, "%.3f sec\n", double(end - beg) / CLOCKS_PER_SEC);
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0