QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#779384 | #9782. NonZero PrefSuf Sums | ucup-team5243 | AC ✓ | 18ms | 10996kb | C++17 | 13.8kb | 2024-11-24 18:45:19 | 2024-11-24 18:45:24 |
Judging History
answer
//#ifdef NACHIA
//#define _GLIBCXX_DEBUG
//#else
//#define NDEBUG
//#endif
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>
#include <functional>
#include <utility>
#include <type_traits>
template<class Elem> struct vec;
template<class Iter>
struct seq_view{
using Ref = typename std::iterator_traits<Iter>::reference;
using Elem = typename std::iterator_traits<Iter>::value_type;
Iter a, b;
Iter begin() const { return a; }
Iter end() const { return b; }
int size() const { return (int)(b-a); }
seq_view(Iter first, Iter last) : a(first), b(last) {}
seq_view sort() const { std::sort(a, b); return *this; }
Ref& operator[](int x) const { return *(a+x); }
template<class F = std::less<Elem>, class ret = vec<int>> ret sorti(F f = F()) const {
ret x(size()); for(int i=0; i<size(); i++) x[i] = i;
x().sort([&](int l, int r){ return f(a[l],a[r]); });
return x;
}
template<class ret = vec<Elem>> ret col() const { return ret(begin(), end()); }
template<class ret = vec<Elem>> ret cumsum() const {
auto res = ret(size() + 1, Elem(0));
for(int i=0; i<size(); i++) res[i+1] = res[i] + operator[](i);
return res;
}
template<class F = std::equal_to<Elem>, class ret = vec<std::pair<Elem, int>>>
ret rle(F eq = F()) const {
auto x = ret();
for(auto& a : (*this)){
if(x.size() == 0 || !eq(x[x.size()-1].first, a)) x.emp(a, 1); else x[x.size()-1].second++;
} return x;
}
template<class F> seq_view sort(F f) const { std::sort(a, b, f); return *this; }
Iter uni() const { return std::unique(a, b); }
Iter lb(const Elem& x) const { return std::lower_bound(a, b, x); }
Iter ub(const Elem& x) const { return std::upper_bound(a, b, x); }
int lbi(const Elem& x) const { return lb(x) - a; }
int ubi(const Elem& x) const { return ub(x) - a; }
seq_view bound(const Elem& l, const Elem& r) const { return { lb(l), lb(r) }; }
template<class F> Iter lb(const Elem& x, F f) const { return std::lower_bound(a, b, x, f); }
template<class F> Iter ub(const Elem& x, F f) const { return std::upper_bound(a, b, x, f); }
template<class F> Iter when_true_to_false(F f) const {
if(a == b) return a;
return std::lower_bound(a, b, *a,
[&](const Elem& x, const Elem&){ return f(x); });
}
seq_view same(Elem x) const { return { lb(x), ub(x) }; }
template<class F> auto map(F f) const {
vec<decltype(f(std::declval<const typename Iter::value_type&>()))> r;
for(auto& x : *this) r.emp(f(x));
return r;
}
Iter max() const { return std::max_element(a, b); }
Iter min() const { return std::min_element(a, b); }
template<class F = std::less<Elem>>
Iter min(F f) const { return std::min_element(a, b, f); }
seq_view rev() const { std::reverse(a, b); return *this; }
};
template<class Elem>
struct vec {
public:
using Base = typename std::vector<Elem>;
using Iter = typename Base::iterator;
using CIter = typename Base::const_iterator;
using View = seq_view<Iter>;
using CView = seq_view<CIter>;
vec(){}
explicit vec(int n, const Elem& value = Elem()) : a(0<n?n:0, value) {}
template <class I2> vec(I2 first, I2 last) : a(first, last) {}
vec(std::initializer_list<Elem> il) : a(std::move(il)) {}
vec(Base b) : a(std::move(b)) {}
operator Base() const { return a; }
Iter begin(){ return a.begin(); }
CIter begin() const { return a.begin(); }
Iter end(){ return a.end(); }
CIter end() const { return a.end(); }
int size() const { return a.size(); }
bool empty() const { return a.empty(); }
Elem& back(){ return a.back(); }
const Elem& back() const { return a.back(); }
vec& sortuni(){ (*this)().sort(); a.erase((*this)().uni(), end()); return *this; }
vec sortunied(){ vec x = *this; x.sortuni(); return x; }
Iter operator()(int x){ return a.begin() + x; }
CIter operator()(int x) const { return a.begin() + x; }
View operator()(int l, int r){ return { (*this)(l), (*this)(r) }; }
CView operator()(int l, int r) const { return { (*this)(l), (*this)(r) }; }
View operator()(){ return (*this)(0,size()); }
CView operator()() const { return (*this)(0,size()); }
Elem& operator[](int x){ return a[x]; }
const Elem& operator[](int x) const { return a[x]; }
Base& operator*(){ return a; }
const Base& operator*() const { return a; }
vec& push(Elem args){
a.push_back(std::move(args));
return *this;
}
template<class... Args>
vec& emp(Args &&... args){
a.emplace_back(std::forward<Args>(args) ...);
return *this;
}
template<class Range>
vec& app(Range& x){ for(auto& v : x){ emp(v); } return *this; }
Elem pop(){ Elem x = std::move(a.back()); a.pop_back(); return x; }
void resize(int sz){ a.resize(sz); }
void reserve(int sz){ a.reserve(sz); }
bool operator==(const vec& r) const { return a == r.a; }
bool operator!=(const vec& r) const { return a != r.a; }
bool operator<(const vec& r) const { return a < r.a; }
bool operator<=(const vec& r) const { return a <= r.a; }
bool operator>(const vec& r) const { return a > r.a; }
bool operator>=(const vec& r) const { return a >= r.a; }
vec<vec<Elem>> pile(int n) const { return vec<vec<Elem>>(n, *this); }
template<class F> vec& filter(F f){
int p = 0;
for(auto& x : a) if(f(x)) std::swap(a[p++],x);
resize(p); return *this;
}
vec& operator+=(const vec& r){ return app(r); }
vec operator+(const vec& r) const { vec x = *this; x += r; return x; }
vec operator*(int t) const { vec res; while(t--){ res += *this; } return res; }
private: Base a;
};
template<class IStr, class U, class T>
IStr& operator>>(IStr& is, vec<std::pair<U,T>>& v){ for(auto& x:v){ is >> x.first >> x.second; } return is; }
template<class IStr, class T>
IStr& operator>>(IStr& is, vec<T>& v){ for(auto& x:v){ is >> x; } return is; }
template<class OStr, class T>
OStr& operator<<(OStr& os, const vec<T>& v){
for(int i=0; i<v.size(); i++){
if(i){ os << ' '; } os << v[i];
} return os;
}
template<class OStr, class U, class T>
OStr& operator<<(OStr& os, const vec<std::pair<U,T>>& v){
for(int i=0; i<v.size(); i++){
if(i){ os << ' '; } os << '(' << v[i].first << ',' << v[i].second << ')';
} return os;
}
#include <cassert>
namespace nachia{
// ax + by = gcd(a,b)
// return ( x, - )
std::pair<long long, long long> ExtGcd(long long a, long long b){
long long x = 1, y = 0;
while(b){
long long u = a / b;
std::swap(a-=b*u, b);
std::swap(x-=y*u, y);
}
return std::make_pair(x, a);
}
} // namespace nachia
namespace nachia{
class DynamicModSupplier{
using u64 = unsigned long long;
using Int = unsigned int;
private:
u64 imod;
Int mod;
// atcoder library
u64 reduce2(u64 z) const noexcept {
// atcoder library
#ifdef _MSC_VER
u64 x; _umul128(z, im, &x);
#else
using u128 = unsigned __int128;
u64 x = (u64)(((u128)(z)*imod) >> 64);
#endif
return z - x * mod;
}
public:
DynamicModSupplier(unsigned int MOD = 998244353) : mod(MOD) {
assert(2 <= MOD);
assert(MOD < (1u << 31));
imod = (u64)(-1) / mod + 1;
}
Int reduce(u64 z) const noexcept {
Int v = reduce2(z);
if(mod <= v) v += mod;
return v;
}
Int add(Int a, Int b) const { a += b; if(a >= mod){ a -= mod; } return a; }
Int sub(Int a, Int b) const { a -= b; if(a >= mod){ a += mod; } return a; }
Int mul(Int a, Int b) const { return reduce((u64)a * b); }
Int muladd(Int a, Int b, Int c) const { return reduce((u64)a * b + c); }
Int inv(Int a) const {
Int v = ExtGcd(a, mod).first;
return (v < mod) ? v : (v + mod);
}
Int pow(Int a, u64 i) const {
Int r = a, ans = 1;
while(i){
if(i & 1) ans = mul(ans, r);
i /= 2;
r = mul(r, r);
}
return ans;
}
Int getMod() const { return mod; }
};
} // namespace nachia
namespace nachia{
template<unsigned int IDENTIFER, class IDENTIFER2 = void>
class DynamicModint{
using Int = unsigned int;
using MyType = DynamicModint;
private:
static DynamicModSupplier _c;
Int v;
template< class Elem >
static Elem SafeMod(Elem x, Int mod){
if(x < 0){
if(0 <= x+mod) return x + mod;
return mod - ((-(x+mod)-1) % mod + 1);
}
return x % mod;
}
public:
DynamicModint() : v(0) {}
DynamicModint(const MyType& r) : v(r.v) {}
MyType& operator=(const MyType&) = default;
DynamicModint(long long x){ v = SafeMod(x, _c.getMod()); }
static MyType raw(Int _v){ MyType res; res.v = _v; return res; }
static void setMod(DynamicModSupplier sup){ _c = std::move(sup); }
MyType operator+=(MyType r){ return v = _c.add(v, r.v); }
MyType operator+(MyType r) const { return raw(_c.add(v, r.v)); }
MyType operator-=(MyType r){ return v = _c.sub(v, r.v); }
MyType operator-(MyType r) const { return raw(_c.sub(v, r.v)); }
MyType operator-() const { return raw(v ? _c.getMod()-v : 0); }
MyType operator*=(MyType r){ return v = _c.mul(v, r.v); }
MyType operator*(MyType r) const { return raw(_c.mul(v, r.v)); }
MyType operator/=(MyType r){ return v = _c.mul(v, _c.inv(r.v)); }
MyType operator/(MyType r) const { return raw(_c.mul(v, _c.inv(r.v))); }
MyType inv() const { return raw(_c.inv(v)); }
MyType pow(unsigned long long r) const { return raw(_c.pow(v, r)); }
MyType mulAdd(MyType mul, MyType add) const { return raw(_c.muladd(v, mul.v, add.v)); }
Int val() const { return v; }
Int operator*() const { return v; }
static Int mod(){ return _c.getMod(); }
};
template<unsigned int IDENTIFER, class IDENTIFER2>
DynamicModSupplier DynamicModint<IDENTIFER, IDENTIFER2>::_c;
} // namespace nachia
using i64 = long long;
using u64 = unsigned long long;
#define rep(i,n) for(int i=0; i<int(n); i++)
const i64 INF = 1001001001001001001;
template<typename A> void chmin(A& l, const A& r){ if(r < l) l = r; }
template<typename A> void chmax(A& l, const A& r){ if(l < r) l = r; }
using namespace std;
using Modint = nachia::DynamicModint<998244353>;
namespace nachia{
template<class Modint>
class Comb{
private:
std::vector<Modint> F;
std::vector<Modint> iF;
public:
void extend(int newN){
int prevN = (int)F.size() - 1;
if(prevN >= newN) return;
F.resize(newN+1);
iF.resize(newN+1);
for(int i=prevN+1; i<=newN; i++) F[i] = F[i-1] * Modint::raw(i);
iF[newN] = F[newN].inv();
for(int i=newN; i>prevN; i--) iF[i-1] = iF[i] * Modint::raw(i);
}
Comb(int n = 1){
F.assign(2, Modint(1));
iF.assign(2, Modint(1));
extend(n);
}
Modint factorial(int n) const { return F[n]; }
Modint invFactorial(int n) const { return iF[n]; }
Modint invOf(int n) const { return iF[n] * F[n-1]; }
Modint comb(int n, int r) const {
if(n < 0 || n < r || r < 0) return Modint(0);
return F[n] * iF[r] * iF[n-r];
}
Modint invComb(int n, int r) const {
if(n < 0 || n < r || r < 0) return Modint(0);
return iF[n] * F[r] * F[n-r];
}
Modint perm(int n, int r) const {
if(n < 0 || n < r || r < 0) return Modint(0);
return F[n] * iF[n-r];
}
Modint invPerm(int n, int r) const {
if(n < 0 || n < r || r < 0) return Modint(0);
return iF[n] * F[n-r];
}
Modint operator()(int n, int r) const { return comb(n,r); }
};
} // namespace nachia
void testcase(){
int N, M; cin >> N >> M;
int P; cin >> P;
Modint::setMod(P);
Modint ans = 0;
{
auto dp = vec<Modint>(N*M*2+2).pile(N+1);
dp[0][N*M] = 1;
rep(i,N){
int z = N*M*2;
for(int j=M; j<=z-M; j++){
dp[i+1][j-M] += dp[i][j];
dp[i+1][j+M+1] -= dp[i][j];
}
rep(j,N*M*2+1) dp[i+1][j+1] += dp[i+1][j];
}
rep(i,N*M*2+1) ans += dp[N][i]; // all
ans -= dp[N][N*M]; // sum = 0;
ans -= Modint(M*2) * Modint(N); // only one nonzero element
}
{
auto comb = nachia::Comb<Modint>(N);
vec<vec<vec<Modint>>> dps(M+1);
dps[0] = vec<Modint>(N+2).pile(N+1);
for(int k=1; k<=M; k++){
auto dp = vec<Modint>(N+2).pile(N+1);
dp[0][0] = 1;
rep(i,N){
for(int j=0; j<=N; j++){
dp[i+1][j] += dp[i][j];
dp[i+1][min(N+1,j+k+1)] -= dp[i][j];
}
rep(j,N+1) dp[i+1][j+1] += dp[i+1][j];
}
swap(dps[k], dp);
}
for(int k=1; k<=M; k++){
for(int m=1; m<=N; m++){
// plus = [k] * m
for(int c=1; c<m; c++){
//cout << "k = " << k << " , m = " << m << " , c = " << c << endl;
// sum minus = k * c
// [k] + (minus, [k]*c) + [k,k,..,k]
int m2 = M / k;
int ok = max(0, min(m2, (m - c) - 2));
//auto delta = (dps[m2][N-m][c] - dps[ok][N-m][c]) * comb(N,m) * 2;
//cout << " delta = " << delta.val() << endl;
ans -= (dps[m2][N-m][c] - dps[ok][N-m][c]) * comb(N,m) * 2;
}
}
}
}
cout << ans.val() << endl;
}
int main(){
ios::sync_with_stdio(false); cin.tie(nullptr);
testcase();
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 3536kb
input:
2 1 998244353
output:
2
result:
ok single line: '2'
Test #2:
score: 0
Accepted
time: 4ms
memory: 4540kb
input:
69 42 696969697
output:
378553557
result:
ok single line: '378553557'
Test #3:
score: 0
Accepted
time: 0ms
memory: 3588kb
input:
2 1 998244353
output:
2
result:
ok single line: '2'
Test #4:
score: 0
Accepted
time: 4ms
memory: 4616kb
input:
69 42 696969697
output:
378553557
result:
ok single line: '378553557'
Test #5:
score: 0
Accepted
time: 0ms
memory: 5400kb
input:
61 75 677323601
output:
34613998
result:
ok single line: '34613998'
Test #6:
score: 0
Accepted
time: 0ms
memory: 3552kb
input:
13 14 670577333
output:
41465431
result:
ok single line: '41465431'
Test #7:
score: 0
Accepted
time: 0ms
memory: 3836kb
input:
14 6 987686347
output:
37536510
result:
ok single line: '37536510'
Test #8:
score: 0
Accepted
time: 0ms
memory: 3804kb
input:
15 12 196428923
output:
29322522
result:
ok single line: '29322522'
Test #9:
score: 0
Accepted
time: 1ms
memory: 3948kb
input:
68 7 786815587
output:
149281835
result:
ok single line: '149281835'
Test #10:
score: 0
Accepted
time: 0ms
memory: 3612kb
input:
3 2 503002109
output:
82
result:
ok single line: '82'
Test #11:
score: 0
Accepted
time: 0ms
memory: 3492kb
input:
13 5 756093197
output:
415698676
result:
ok single line: '415698676'
Test #12:
score: 0
Accepted
time: 0ms
memory: 3592kb
input:
2 3 646574611
output:
30
result:
ok single line: '30'
Test #13:
score: 0
Accepted
time: 2ms
memory: 3836kb
input:
39 68 120037189
output:
43217507
result:
ok single line: '43217507'
Test #14:
score: 0
Accepted
time: 0ms
memory: 3536kb
input:
13 4 423132517
output:
360231790
result:
ok single line: '360231790'
Test #15:
score: 0
Accepted
time: 0ms
memory: 3820kb
input:
14 3 309713387
output:
94215386
result:
ok single line: '94215386'
Test #16:
score: 0
Accepted
time: 1ms
memory: 3784kb
input:
24 77 886983941
output:
211636479
result:
ok single line: '211636479'
Test #17:
score: 0
Accepted
time: 0ms
memory: 3600kb
input:
3 3 504388063
output:
270
result:
ok single line: '270'
Test #18:
score: 0
Accepted
time: 0ms
memory: 3616kb
input:
3 1 936205423
output:
8
result:
ok single line: '8'
Test #19:
score: 0
Accepted
time: 0ms
memory: 3528kb
input:
3 3 295983139
output:
270
result:
ok single line: '270'
Test #20:
score: 0
Accepted
time: 0ms
memory: 3624kb
input:
10 15 446169107
output:
149884328
result:
ok single line: '149884328'
Test #21:
score: 0
Accepted
time: 1ms
memory: 3968kb
input:
37 18 833753929
output:
592917251
result:
ok single line: '592917251'
Test #22:
score: 0
Accepted
time: 0ms
memory: 3772kb
input:
11 3 998773403
output:
860630017
result:
ok single line: '860630017'
Test #23:
score: 0
Accepted
time: 1ms
memory: 3712kb
input:
14 85 688036639
output:
347188409
result:
ok single line: '347188409'
Test #24:
score: 0
Accepted
time: 0ms
memory: 3644kb
input:
3 3 844621907
output:
270
result:
ok single line: '270'
Test #25:
score: 0
Accepted
time: 0ms
memory: 3592kb
input:
3 4 204335891
output:
620
result:
ok single line: '620'
Test #26:
score: 0
Accepted
time: 0ms
memory: 3492kb
input:
7 8 113007667
output:
58946097
result:
ok single line: '58946097'
Test #27:
score: 0
Accepted
time: 1ms
memory: 3548kb
input:
4 1 637268377
output:
22
result:
ok single line: '22'
Test #28:
score: 0
Accepted
time: 1ms
memory: 3608kb
input:
11 14 391637237
output:
303270280
result:
ok single line: '303270280'
Test #29:
score: 0
Accepted
time: 0ms
memory: 3480kb
input:
3 2 208286231
output:
82
result:
ok single line: '82'
Test #30:
score: 0
Accepted
time: 0ms
memory: 3528kb
input:
2 11 662696483
output:
462
result:
ok single line: '462'
Test #31:
score: 0
Accepted
time: 1ms
memory: 3944kb
input:
19 55 974135299
output:
887460557
result:
ok single line: '887460557'
Test #32:
score: 0
Accepted
time: 0ms
memory: 3536kb
input:
6 8 417027509
output:
23351024
result:
ok single line: '23351024'
Test #33:
score: 0
Accepted
time: 0ms
memory: 3628kb
input:
8 13 624006587
output:
353008442
result:
ok single line: '353008442'
Test #34:
score: 0
Accepted
time: 0ms
memory: 3624kb
input:
10 10 740294671
output:
79436611
result:
ok single line: '79436611'
Test #35:
score: 0
Accepted
time: 0ms
memory: 3608kb
input:
11 10 394088657
output:
161476458
result:
ok single line: '161476458'
Test #36:
score: 0
Accepted
time: 0ms
memory: 3640kb
input:
9 27 562853573
output:
135252259
result:
ok single line: '135252259'
Test #37:
score: 0
Accepted
time: 0ms
memory: 3816kb
input:
8 3 829129009
output:
5349034
result:
ok single line: '5349034'
Test #38:
score: 0
Accepted
time: 3ms
memory: 4084kb
input:
51 49 924010279
output:
815049368
result:
ok single line: '815049368'
Test #39:
score: 0
Accepted
time: 0ms
memory: 3548kb
input:
12 2 308466749
output:
223013998
result:
ok single line: '223013998'
Test #40:
score: 0
Accepted
time: 0ms
memory: 3548kb
input:
7 4 567557693
output:
4502296
result:
ok single line: '4502296'
Test #41:
score: 0
Accepted
time: 2ms
memory: 4104kb
input:
36 93 943780729
output:
13599465
result:
ok single line: '13599465'
Test #42:
score: 0
Accepted
time: 0ms
memory: 3556kb
input:
2 1 828681127
output:
2
result:
ok single line: '2'
Test #43:
score: 0
Accepted
time: 0ms
memory: 3592kb
input:
3 3 534160729
output:
270
result:
ok single line: '270'
Test #44:
score: 0
Accepted
time: 0ms
memory: 3536kb
input:
7 12 920925433
output:
453086694
result:
ok single line: '453086694'
Test #45:
score: 0
Accepted
time: 0ms
memory: 3596kb
input:
3 2 440546987
output:
82
result:
ok single line: '82'
Test #46:
score: 0
Accepted
time: 2ms
memory: 3684kb
input:
90 9 291269963
output:
72560304
result:
ok single line: '72560304'
Test #47:
score: 0
Accepted
time: 1ms
memory: 3732kb
input:
38 10 867575113
output:
165530481
result:
ok single line: '165530481'
Test #48:
score: 0
Accepted
time: 0ms
memory: 3868kb
input:
48 37 152663531
output:
135425620
result:
ok single line: '135425620'
Test #49:
score: 0
Accepted
time: 0ms
memory: 3580kb
input:
15 15 991731803
output:
102703562
result:
ok single line: '102703562'
Test #50:
score: 0
Accepted
time: 18ms
memory: 10996kb
input:
100 100 696969697
output:
313377809
result:
ok single line: '313377809'
Extra Test:
score: 0
Extra Test Passed