結果
| 問題 | No.3540 Arise |
| コンテスト | |
| ユーザー |
nauclhlt
|
| 提出日時 | 2026-04-01 12:18:16 |
| 言語 | C++17 (gcc 15.2.0 + boost 1.89.0) |
| 結果 |
AC
|
| 実行時間 | 968 ms / 2,500 ms |
| コード長 | 8,260 bytes |
| 記録 | |
| コンパイル時間 | 2,825 ms |
| コンパイル使用メモリ | 251,416 KB |
| 実行使用メモリ | 7,976 KB |
| 最終ジャッジ日時 | 2026-05-08 20:55:49 |
| 合計ジャッジ時間 | 13,156 ms |
|
ジャッジサーバーID (参考情報) |
judge2_1 / judge1_1 |
(要ログイン)
| サブタスク | 配点 | 結果 |
|---|---|---|
| サブタスク1 | 30 % | AC * 19 |
| サブタスク2 | 70 % | AC * 22 |
| 合計 | 3.5 * 100% = 350 点 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define CONST_MOD 998244353LL
// #define CONST_MOD 1000000007L
struct ModInt
{
long long Value;
public:
ModInt()
{
Value = 0L;
}
ModInt(long long value)
{
Value = value;
}
ModInt Power(long long exp) const
{
if (exp <= -1L)
{
return ModInt(1L) / Power(-exp);
}
if (exp == 0L)
return 1L;
if (exp == 1L)
return *this;
ModInt m = Power(exp / 2L);
m = m * m;
if (exp % 2L == 1L)
{
m = m * (*this);
}
return m;
}
ModInt Inv() const
{
return this->Power(CONST_MOD - 2L);
}
ModInt operator+() const
{
return *this;
}
ModInt operator-() const
{
return ModInt(-Value);
}
friend ModInt operator+(const ModInt& left, const ModInt& right)
{
return ModInt(SafeMod(left.Value + right.Value));
}
friend ModInt operator+(const ModInt& left, const long long& right)
{
return ModInt(SafeMod(left.Value + right));
}
friend ModInt operator+(const long long& left, const ModInt& right)
{
return ModInt(SafeMod(left + right.Value));
}
ModInt& operator+=(const ModInt& x)
{
Value += x.Value;
Value = SafeMod(Value);
return *this;
}
ModInt& operator+=(const long long& x)
{
Value += x;
Value = SafeMod(Value);
return *this;
}
friend ModInt operator-(const ModInt& left, const ModInt& right)
{
return ModInt(SafeMod(left.Value - right.Value));
}
friend ModInt operator-(const ModInt& left, const long long& right)
{
return ModInt(SafeMod(left.Value - right));
}
friend ModInt operator-(const long long& left, const ModInt& right)
{
return ModInt(SafeMod(left - right.Value));
}
ModInt& operator-=(const ModInt& x)
{
Value -= x.Value;
Value = SafeMod(Value);
return *this;
}
ModInt& operator-=(const long long& x)
{
Value -= x;
Value = SafeMod(Value);
return *this;
}
friend ModInt operator*(const ModInt& left, const ModInt& right)
{
return ModInt(SafeMod(left.Value * right.Value));
}
friend ModInt operator*(const ModInt& left, const long long& right)
{
return ModInt(SafeMod(left.Value * right));
}
friend ModInt operator*(const long long& left, const ModInt& right)
{
return ModInt(SafeMod(left * right.Value));
}
ModInt& operator*=(const ModInt& x)
{
Value *= x.Value;
Value = SafeMod(Value);
return *this;
}
ModInt& operator*=(const long long& x)
{
Value *= x;
Value = SafeMod(Value);
return *this;
}
friend ModInt operator /(const ModInt& left, const ModInt& right)
{
ModInt inv = right.Inv();
return ModInt(SafeMod(left.Value * inv.Value));
}
friend ModInt operator/(const ModInt& left, const long long& right)
{
return ModInt(SafeMod(left.Value * ModInt(right).Inv().Value));
}
friend ModInt operator/(const long long& left, const ModInt& right)
{
return ModInt(SafeMod(left * right.Inv().Value));
}
ModInt& operator/=(const ModInt& x)
{
Value *= x.Inv().Value;
Value = SafeMod(Value);
return *this;
}
ModInt& operator/=(const long long& x)
{
Value *= ModInt(x).Inv().Value;
Value = SafeMod(Value);
return *this;
}
ModInt& operator++()
{
++Value;
Value = SafeMod(Value);
return *this;
}
ModInt operator++(int)
{
ModInt temp = *this;
Value++;
Value = SafeMod(Value);
return temp;
}
ModInt& operator--()
{
--Value;
Value = SafeMod(Value);
return *this;
}
ModInt operator--(int)
{
ModInt temp = *this;
Value--;
Value = SafeMod(Value);
return temp;
}
inline static ModInt One()
{
return ModInt(1L);
}
static ModInt Combination(long long n, long long r)
{
ModInt c = 1L;
for (ModInt i = 1; i.Value <= r; i++)
{
c = c * (ModInt(n) - i + ModInt::One()) / i;
}
return c;
}
private:
inline static long long SafeMod(long long a)
{
a %= CONST_MOD;
if (a < 0)
{
a += CONST_MOD;
}
return a;
}
};
class ModCache
{
private:
vector<ModInt> _factorial;
vector<ModInt> _inverseFactorial;
vector<ModInt> _inverse;
public:
ModCache(int max)
{
_factorial.resize(max + 1);
_inverseFactorial.resize(max + 1);
_inverse.resize(max + 1);
_factorial[0] = 1;
_inverseFactorial[0] = 1LL;
_inverse[1] = 1LL;
for (long p = 1; p <= max; p++)
{
_factorial[p] = _factorial[p - 1] * p;
if (p > 1)
{
_inverse[p] = -(CONST_MOD / p) * _inverse[CONST_MOD % p];
}
_inverseFactorial[p] = _inverseFactorial[p - 1] * _inverse[p];
}
}
ModInt Combination(int n, int r)
{
if (n < 0 || r < 0 || n < r) return 0;
return _factorial[n] * (_inverseFactorial[n - r] * _inverseFactorial[r]);
}
ModInt Permutation(int n, int r)
{
return _factorial[n] * _inverseFactorial[n - r];
}
ModInt Factorial(int n)
{
return _factorial[n];
}
ModInt InverseFactorial(int n)
{
return _inverseFactorial[n];
}
ModInt Inverse(int n)
{
return _inverse[n];
}
};
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N;
cin >> N;
vector<ll> A(N);
for (int i = 0; i < N; i++)
{
cin >> A[i];
}
sort(A.begin(), A.end());
vector<ll> B;
vector<int> C;
for (int i = 0; i < N; i++)
{
if (B.empty())
{
B.push_back(A[i]);
C.push_back(1);
continue;
}
if (B.back() == A[i])
{
int pc = C.back();
C.pop_back();
C.push_back(pc + 1);
}
else
{
B.push_back(A[i]);
C.push_back(1);
}
}
int K = B.size();
vector<ModInt> invB(K);
for (int i = 0; i < K; i++)
{
invB[i] = ((ModInt)B[i]).Inv();
}
ModInt ans = 0LL;
for (int i = 0; i < N; i++)
{
ans += (A[i] + 1) / (ModInt)2LL;
}
vector<ModInt> F(N + 3);
for (int x = 1; x <= min(B[0], (ll)(N + 2)); x++)
{
ModInt left = 1LL;
ModInt right = 1LL;
for (int i = 1; i < K; i++)
{
right *= ((ModInt)(B[i] - x) * invB[i]).Power(C[i]);
}
for (int k = 0; k < K; k++)
{
F[x] += (B[k] - x) * left * right * (
((B[k] - x + 1) * invB[k]).Power(C[k]) - ((B[k] - x) * invB[k]).Power(C[k])
);
left *= ((B[k] - x + 1) * invB[k]).Power(C[k]);
if (k < K - 1)
{
right /= ((ModInt)(B[k + 1] - x) * invB[k + 1]).Power(C[k + 1]);
}
}
}
for (int j = 2; j <= N + 2; j++)
{
F[j] += F[j - 1];
}
if (B[0] <= N + 2)
{
ans += F[B[0]];
cout << ans.Value << endl;
return 0;
}
ModCache cache(N + 100);
vector<ModInt> prefix(N + 3);
vector<ModInt> suffix(N + 3);
prefix[0] = 1LL;
suffix[N + 2] = 1LL;
for (int i = 1; i <= N + 2; i++)
{
prefix[i] = prefix[i - 1] * (B[0] - i);
}
for (int i = N + 1; i >= 0; i--)
{
suffix[i] = suffix[i + 1] * (B[0] - i - 1);
}
for (int i = 1; i <= N + 2; i++)
{
long sign = (i - N + 2) % 2 == 0 ? 1 : -1;
ans += F[i] * (prefix[i - 1] * suffix[i]) * (cache.InverseFactorial(i - 1) * sign * cache.InverseFactorial(N + 2 - i));
}
cout << ans.Value << endl;
}
nauclhlt