結果
| 問題 |
No.3297 Bake Cookies
|
| コンテスト | |
| ユーザー |
kaliafluorido
|
| 提出日時 | 2025-10-05 19:14:49 |
| 言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 77 ms / 2,000 ms |
| コード長 | 14,876 bytes |
| コンパイル時間 | 5,992 ms |
| コンパイル使用メモリ | 359,460 KB |
| 実行使用メモリ | 7,716 KB |
| 最終ジャッジ日時 | 2025-10-05 19:14:59 |
| 合計ジャッジ時間 | 9,192 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 27 |
ソースコード
#pragma region header
#ifdef LOCAL_ENV
#include <header_all.hpp>
#else
#include <bits/stdc++.h>
#include <atcoder/all>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/tag_and_trait.hpp>
#define dump(...)
#define CPP_DUMP_SET_OPTION(...)
#define CPP_DUMP_SET_OPTION_GLOBAL(...)
#define CPP_DUMP_DEFINE_EXPORT_OBJECT(...)
#define CPP_DUMP_DEFINE_EXPORT_ENUM(...)
#define CPP_DUMP_DEFINE_EXPORT_OBJECT_GENERIC(...)
#endif
using namespace std;
using namespace atcoder;
using namespace __gnu_pbds;
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define FOR(i, start, end) for (int i = start; i < (int)(end); ++i)
#define RFOR(i, rstart, rend) for (int i = rstart; i >= (int)(rend); --i)
#define REP(i, end) FOR(i, 0, end)
#define BIT(x, i) (((x)>>(i))&1)
using ll = long long;
using ull = unsigned long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using pli = pair<ll, int>;
constexpr ll LINF = 1LL << 60;
constexpr int INF = 1 << 30;
template <typename T> using TREE = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename T> using Graph = vector<vector<T>>;
template <typename T> using PQ = priority_queue<T, vector<T>, greater<T>>;
void yes(bool expr) {cout << (expr ? "Yes" : "No") << "\n";}
template<typename T> bool chmax(T &a, const T &b) { if (a<b){a=b; return true;} else{return false;}}
template<typename T> bool chmin(T &a, const T &b) { if (b<a){a=b; return true;} else{return false;}}
template<typename T> istream &operator>>(istream&is,vector<T>&v){for(T &in:v){is>>in;}return is;}
template<typename T> ostream &operator<<(ostream&os,const vector<T>&v){for(auto it=v.begin();it!=v.end();){os<<*it<<((++it)!=v.end()?" ":"");}return os;}
void pp(){cout << "\n";}
template<typename T> void pp(const T &val) {cout << val << "\n";}
template<typename T, typename... Ts> void pp(const T &a, const Ts &...b){cout << a;(cout << ... << (cout << " ", b));cout << "\n";}
// https://nyaannyaan.github.io/library/hashmap/hashmap.hpp
namespace HashMapImpl {
using u32 = uint32_t;
using u64 = uint64_t;
template <typename Key, typename Data>
struct HashMapBase;
template <typename Key, typename Data>
struct itrB {
using iterator_category = std::bidirectional_iterator_tag;
using value_type = Data;
using difference_type = ptrdiff_t;
using pointer = Data*;
using reference = Data&;
u32 i;
HashMapBase<Key, Data>* p;
explicit constexpr itrB() : i(0), p(nullptr) {}
explicit constexpr itrB(u32 _i, HashMapBase<Key, Data>* _p) : i(_i), p(_p) {}
explicit constexpr itrB(u32 _i, const HashMapBase<Key, Data>* _p)
: i(_i), p(const_cast<HashMapBase<Key, Data>*>(_p)) {}
friend void swap(itrB& l, itrB& r) { swap(l.i, r.i), swap(l.p, r.p); }
friend bool operator==(const itrB& l, const itrB& r) { return l.i == r.i; }
friend bool operator!=(const itrB& l, const itrB& r) { return l.i != r.i; }
const reference operator*() const {
return const_cast<const HashMapBase<Key, Data>*>(p)->data[i];
}
reference operator*() { return p->data[i]; }
pointer operator->() const { return &(p->data[i]); }
itrB& operator++() {
assert(i != p->cap && "itr::operator++()");
do {
i++;
if (i == p->cap) break;
if (p->occupied_flag[i] && !p->deleted_flag[i]) break;
} while (true);
return (*this);
}
itrB operator++(int) {
itrB it(*this);
++(*this);
return it;
}
itrB& operator--() {
do {
i--;
if (p->occupied_flag[i] && !p->deleted_flag[i]) break;
assert(i != 0 && "itr::operator--()");
} while (true);
return (*this);
}
itrB operator--(int) {
itrB it(*this);
--(*this);
return it;
}
};
template <typename Key, typename Data>
struct HashMapBase {
using u32 = uint32_t;
using u64 = uint64_t;
using iterator = itrB<Key, Data>;
using itr = iterator;
protected:
template <typename K>
inline u64 randomized(const K& key) const {
return u64(key) ^ r;
}
template <typename K,
enable_if_t<is_same<K, Key>::value, nullptr_t> = nullptr,
enable_if_t<is_integral<K>::value, nullptr_t> = nullptr>
inline u32 inner_hash(const K& key) const {
return (randomized(key) * 11995408973635179863ULL) >> shift;
}
template <
typename K, enable_if_t<is_same<K, Key>::value, nullptr_t> = nullptr,
enable_if_t<is_integral<decltype(K::first)>::value, nullptr_t> = nullptr,
enable_if_t<is_integral<decltype(K::second)>::value, nullptr_t> = nullptr>
inline u32 inner_hash(const K& key) const {
u64 a = randomized(key.first), b = randomized(key.second);
a *= 11995408973635179863ULL;
b *= 10150724397891781847ULL;
return (a + b) >> shift;
}
template <typename K,
enable_if_t<is_same<K, Key>::value, nullptr_t> = nullptr,
enable_if_t<is_integral<typename K::value_type>::value, nullptr_t> =
nullptr>
inline u32 inner_hash(const K& key) const {
static constexpr u64 mod = (1LL << 61) - 1;
static constexpr u64 base = 950699498548472943ULL;
u64 res = 0;
for (auto& elem : key) {
__uint128_t x = __uint128_t(res) * base + (randomized(elem) & mod);
res = (x & mod) + (x >> 61);
}
__uint128_t x = __uint128_t(res) * base;
res = (x & mod) + (x >> 61);
if (res >= mod) res -= mod;
return res >> (shift - 3);
}
template <typename D = Data,
enable_if_t<is_same<D, Key>::value, nullptr_t> = nullptr>
inline u32 hash(const D& dat) const {
return inner_hash(dat);
}
template <
typename D = Data,
enable_if_t<is_same<decltype(D::first), Key>::value, nullptr_t> = nullptr>
inline u32 hash(const D& dat) const {
return inner_hash(dat.first);
}
template <typename D = Data,
enable_if_t<is_same<D, Key>::value, nullptr_t> = nullptr>
inline Key data_to_key(const D& dat) const {
return dat;
}
template <
typename D = Data,
enable_if_t<is_same<decltype(D::first), Key>::value, nullptr_t> = nullptr>
inline Key data_to_key(const D& dat) const {
return dat.first;
}
void reallocate(u32 ncap) {
vector<Data> ndata(ncap);
vector<bool> nf(ncap);
shift = 64 - __lg(ncap);
for (u32 i = 0; i < cap; i++) {
if (occupied_flag[i] && !deleted_flag[i]) {
u32 h = hash(data[i]);
while (nf[h]) h = (h + 1) & (ncap - 1);
ndata[h] = move(data[i]);
nf[h] = true;
}
}
data.swap(ndata);
occupied_flag.swap(nf);
cap = ncap;
occupied = s;
deleted_flag.resize(cap);
fill(std::begin(deleted_flag), std::end(deleted_flag), false);
}
inline bool extend_rate(u32 x) const { return x * 2 >= cap; }
inline bool shrink_rate(u32 x) const {
return HASHMAP_DEFAULT_SIZE < cap && x * 10 <= cap;
}
inline void extend() { reallocate(cap << 1); }
inline void shrink() { reallocate(cap >> 1); }
public:
u32 cap, s, occupied;
vector<Data> data;
vector<bool> occupied_flag, deleted_flag;
u32 shift;
static u64 r;
static constexpr uint32_t HASHMAP_DEFAULT_SIZE = 4;
explicit HashMapBase()
: cap(HASHMAP_DEFAULT_SIZE),
s(0),
occupied(0),
data(cap),
occupied_flag(cap),
deleted_flag(cap),
shift(64 - __lg(cap)) {}
itr begin() const {
u32 h = 0;
while (h != cap) {
if (occupied_flag[h] && !deleted_flag[h]) break;
h++;
}
return itr(h, this);
}
itr end() const { return itr(this->cap, this); }
friend itr begin(const HashMapBase& h) { return h.begin(); }
friend itr end(const HashMapBase& h) { return h.end(); }
itr find(const Key& key) const {
u32 h = inner_hash(key);
while (true) {
if (occupied_flag[h] == false) return this->end();
if (data_to_key(data[h]) == key) {
if (deleted_flag[h] == true) return this->end();
return itr(h, this);
}
h = (h + 1) & (cap - 1);
}
}
bool contain(const Key& key) const { return find(key) != this->end(); }
itr insert(const Data& d) {
u32 h = hash(d);
while (true) {
if (occupied_flag[h] == false) {
if (extend_rate(occupied + 1)) {
extend();
h = hash(d);
continue;
}
data[h] = d;
occupied_flag[h] = true;
++occupied, ++s;
return itr(h, this);
}
if (data_to_key(data[h]) == data_to_key(d)) {
if (deleted_flag[h] == true) {
data[h] = d;
deleted_flag[h] = false;
++s;
}
return itr(h, this);
}
h = (h + 1) & (cap - 1);
}
}
// tips for speed up :
// if return value is unnecessary, make argument_2 false.
itr erase(itr it, bool get_next = true) {
if (it == this->end()) return this->end();
s--;
if (!get_next) {
this->deleted_flag[it.i] = true;
if (shrink_rate(s)) shrink();
return this->end();
}
itr nxt = it;
nxt++;
this->deleted_flag[it.i] = true;
if (shrink_rate(s)) {
Data d = data[nxt.i];
shrink();
it = find(data_to_key(d));
}
return nxt;
}
itr erase(const Key& key) { return erase(find(key)); }
int count(const Key& key) { return find(key) == end() ? 0 : 1; }
bool empty() const { return s == 0; }
int size() const { return s; }
void clear() {
fill(std::begin(occupied_flag), std::end(occupied_flag), false);
fill(std::begin(deleted_flag), std::end(deleted_flag), false);
s = occupied = 0;
}
void reserve(int n) {
if (n <= 0) return;
n = 1 << min(23, __lg(n) + 2);
if (cap < u32(n)) reallocate(n);
}
};
template <typename Key, typename Data>
uint64_t HashMapBase<Key, Data>::r =
chrono::duration_cast<chrono::nanoseconds>(
chrono::high_resolution_clock::now().time_since_epoch())
.count();
} // namespace HashMapImpl
/**
* @brief Hash Map(base) (ハッシュマップ・基底クラス)
*/
#line 4 "hashmap/hashmap.hpp"
template <typename Key, typename Val>
struct HashMap : HashMapImpl::HashMapBase<Key, pair<Key, Val>> {
using base = typename HashMapImpl::HashMapBase<Key, pair<Key, Val>>;
using HashMapImpl::HashMapBase<Key, pair<Key, Val>>::HashMapBase;
using Data = pair<Key, Val>;
Val& operator[](const Key& k) {
typename base::u32 h = base::inner_hash(k);
while (true) {
if (base::occupied_flag[h] == false) {
if (base::extend_rate(base::occupied + 1)) {
base::extend();
h = base::hash(k);
continue;
}
base::data[h].first = k;
base::data[h].second = Val();
base::occupied_flag[h] = true;
++base::occupied, ++base::s;
return base::data[h].second;
}
if (base::data[h].first == k) {
if (base::deleted_flag[h] == true) {
base::data[h].second = Val();
base::deleted_flag[h] = false;
++base::s;
}
return base::data[h].second;
}
h = (h + 1) & (base::cap - 1);
}
}
typename base::itr emplace(const Key& key, const Val& val) {
return base::insert(Data(key, val));
}
};
// https://nyaannyaan.github.io/library/hashmap/hashset.hpp
template <typename Key>
struct HashSet : HashMapImpl::HashMapBase<Key, Key> {
using HashMapImpl::HashMapBase<Key, Key>::HashMapBase;
};
/* 回文判定 */ template<typename T> bool isPalindrome(const T &s){int sz=s.size(); REP(i,sz/2){if(s[i]!=s[sz-1-i])return false;} return true;}
/* 座標圧縮 */ template<typename T> vector<int> compress(const vector<T>&A){vector<int> ret(A.size()); auto tmp = A; sort(ALL(tmp)); tmp.erase(unique(ALL(tmp)), tmp.end()); REP(i,A.size()) ret[i] = lower_bound(ALL(tmp), A[i]) - tmp.begin(); return ret;}
/* 約数列挙 整数nの約数のvectorを返す */ vector<ll> enumdiv(ll n){vector<ll>s; for(ll i = 1;i*i<=n;i++){if(n%i==0){s.push_back(i);if(i*i!=n)s.push_back(n/i);}}return s;}
/* 素因数分解 pair<素数、指数>のvectorを返す */ vector<pli> primeDecomposition(ll x){vector<pli> ret;int i=2,sq=99,d=2;while(i<=sq){int k=0;while(x%i==0){x/=i;++k;}if(k>0){ret.emplace_back(i,k);}if(k>0 || i==97) {sq = sqrt(x)+0.5;}if(i<4){i = (i<<1)-1;}else{i += d;d ^= 6;}}if(x>1) ret.emplace_back(x,1);return ret;}
/* エラトステネスの篩 n未満の素数を列挙。isprimeには素数かどうかが入っている */ vector<bool> isprime;vector<int> era(int n) {isprime.resize(n, true);vector<int> res;isprime[0] = false; isprime[1] = false;for (int i = 2; i < n; ++i){if (isprime[i]) {res.push_back(i);for (int j = i*2; j < n; j += i) isprime[j] = false;}}return res;}
/* トポロジカルソート */ vector<int> topo_sort(const Graph<int> &G){int n = G.size();vector<int> deg(n), ret;for(const auto &v:G)for(const auto &to:v) ++deg[to];queue<int> que;REP(i,n) if(deg[i]==0)que.push(i);while(!que.empty()){const int from = que.front();que.pop();ret.push_back(from);for(const auto &to:G[from])if(--deg[to]==0) que.push(to);}return ret;};
/* 拡張ユークリッドの互除法 [gcd,x,y] ax+by=gcd(a,b) */ tuple<ll,ll,ll> ex_gcd(ll a, ll b){if(b==0) return {a,1,0}; auto [g,x,y] = ex_gcd(b, a%b); return {g,y,x-a/b*y};}
/* 辞書順で次の分割数を求める */ template<typename T> bool next_partition(vector<T> &a){const int n = a.size(); if(n<=1) {return false;} T sum=a[n-1]; a.pop_back(); while(true){T x = a.back(); a.pop_back(); sum += x; if(a.empty() || a.back() > x){a.push_back(x+1); a.resize(a.size()+sum-x-1, 1); break;}} return true;}
/* 切り上げ割り算。ans以上の最小の整数を返す ceil_div(10,3) = 4, ceil_div(10,-3) = -3 */ ll ceil_div(ll a, ll b) { return a/b + (a%b && (a^b)>=0); }
/* 整数sqrt */ ll isqrt(ll n){assert(n>0);ll ok=1,ng=n;while(ng-ok>1){ll mid=ok+((ng-ok)>>1);if(mid<=n/mid){ok=mid;}else{ng=mid;}}return ok;}
/* オーバーフローチェック */ template<typename T, typename U> bool is_safe_mul(const T a, const U b){using R=decltype(a*b);if(a==0||b==0)return true;return static_cast<R>(a)<=numeric_limits<R>::max()/static_cast<R>(b);}
using mint = modint998244353;
//using mint = modint1000000007;
//using mint = modint;
istream &operator>>(istream&is,mint&p){ll x;cin >> x;p=x; return is;}
ostream &operator<<(ostream&os,const mint&p){os << p.val();return os;}
#pragma endregion header
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
ll n,m,t;
cin >> n >> m >> t;
vector<int> a(m);
REP(i,m) cin >> a[i],--a[i];
vector<int> cnt(n);
REP(i,m) cnt[a[i]]++;
auto check = [&](int x) -> bool {
int num = 0;
ll add = 0;
REP(i,n){
num += min(cnt[i], x);
add += (x-min(cnt[i], x))/t;
}
return num + add >= m;
};
int ng = 0, ok = m+1;
while(ok-ng>1){
int mid = (ok+ng)/2;
if(check(mid)) ok = mid;
else ng = mid;
}
pp(ok);
return 0;
}
kaliafluorido