#include <bits/stdc++.h>
#define f first
#define s second
#define pb push_back
#define mp make_pair
#define ins insert
#define er erase
#define siz size()
#define siz1 size()-1
#define ll long long
#define ull unsigned long long
#define all(v) v.begin(), v.end()
#define FORN(i, n) for(int i=1; i<=(int)n; i++)
#define FOR(i,p,k) for(int i=(int)p; i<=(int)k; i++)
#define FORD(i, k, p) for(int i=(int)k; i>=(int)p; i--)
#define FOR0(i, n) for(int i=(int)n; i>=0; i--)
#define FOR1(i, n) for(int i=(int)n; i>=1; i--)
#define FORV(i, vec) for(auto i = vec.begin(); i != vec.end(); ++i)
#define TURBO ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define END cerr<<"TIME: "<<1.0 * clock() / CLOCKS_PER_SEC<<endl;
#define VI vector <int>
#define VP vector <pair<int, int>>
#define VIP vector <pair<int, pair<int, int>>>
#define VPP vector <pair<pair<int, int>, pair<int, int>>>
#define MII map<int, int>
#define MLL map<ll, ll>
#define PII pair<int, int>
#define PLL pair<ll, ll>
#define MAX 1e9 + 10
#define MIN -1e9 + 10
using namespace std;
int COUNT_FROM[10000000+10];
int COUNT_TO[10000000+10];
int PREFIX_COUNT_FROM[10000000+10];
int PREFIX_COUNT_TO[10000000+10];
int n, m, p;
void COUNT_PREFIXES()
{
PREFIX_COUNT_FROM[1] = COUNT_FROM[1];
PREFIX_COUNT_TO[1] = COUNT_TO[1];
for(int i=2; i<=m; i++)
{
PREFIX_COUNT_FROM[i] = COUNT_FROM[i] + PREFIX_COUNT_FROM[i-1];
PREFIX_COUNT_TO[i] = COUNT_TO[i] + PREFIX_COUNT_TO[i-1];
if (PREFIX_COUNT_FROM[i] >= p)
PREFIX_COUNT_FROM[i] -= p;
if (PREFIX_COUNT_TO[i] >= p)
PREFIX_COUNT_TO[i] -= p;
}
}
void MAKE_COUNT_FROM()
{
for(int i=1; i<=m; i++)
COUNT_FROM[i] = COUNT_TO[m-i+1];
}
int main()
{
TURBO;
cin>>n>>m>>p;
for(int i=1; i<=m; i++)
COUNT_TO[i] = i % p;
MAKE_COUNT_FROM();
COUNT_PREFIXES();
ll result = 0;
ll diff;
for(int pref_len=2; pref_len<=n; pref_len++)
{
ll all_options = PREFIX_COUNT_FROM[m];
ll prefixowa_baza_pseudokwadratowa = 0;
for(int konc=1; konc<=m; konc++)
{
prefixowa_baza_pseudokwadratowa += PREFIX_COUNT_TO[konc-1];
if (prefixowa_baza_pseudokwadratowa >= p)
prefixowa_baza_pseudokwadratowa -= p;
result = all_options * konc;
result %= p;
result -= prefixowa_baza_pseudokwadratowa;
diff = PREFIX_COUNT_FROM[m] - PREFIX_COUNT_FROM[konc];
result -= diff * konc;
result %= p;
result += p;
result %= p;
COUNT_TO[konc] = result;
}
MAKE_COUNT_FROM();
COUNT_PREFIXES();
}
cout<<PREFIX_COUNT_FROM[m];
return 0;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | #include <bits/stdc++.h> #define f first #define s second #define pb push_back #define mp make_pair #define ins insert #define er erase #define siz size() #define siz1 size()-1 #define ll long long #define ull unsigned long long #define all(v) v.begin(), v.end() #define FORN(i, n) for(int i=1; i<=(int)n; i++) #define FOR(i,p,k) for(int i=(int)p; i<=(int)k; i++) #define FORD(i, k, p) for(int i=(int)k; i>=(int)p; i--) #define FOR0(i, n) for(int i=(int)n; i>=0; i--) #define FOR1(i, n) for(int i=(int)n; i>=1; i--) #define FORV(i, vec) for(auto i = vec.begin(); i != vec.end(); ++i) #define TURBO ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); #define END cerr<<"TIME: "<<1.0 * clock() / CLOCKS_PER_SEC<<endl; #define VI vector <int> #define VP vector <pair<int, int>> #define VIP vector <pair<int, pair<int, int>>> #define VPP vector <pair<pair<int, int>, pair<int, int>>> #define MII map<int, int> #define MLL map<ll, ll> #define PII pair<int, int> #define PLL pair<ll, ll> #define MAX 1e9 + 10 #define MIN -1e9 + 10 using namespace std; int COUNT_FROM[10000000+10]; int COUNT_TO[10000000+10]; int PREFIX_COUNT_FROM[10000000+10]; int PREFIX_COUNT_TO[10000000+10]; int n, m, p; void COUNT_PREFIXES() { PREFIX_COUNT_FROM[1] = COUNT_FROM[1]; PREFIX_COUNT_TO[1] = COUNT_TO[1]; for(int i=2; i<=m; i++) { PREFIX_COUNT_FROM[i] = COUNT_FROM[i] + PREFIX_COUNT_FROM[i-1]; PREFIX_COUNT_TO[i] = COUNT_TO[i] + PREFIX_COUNT_TO[i-1]; if (PREFIX_COUNT_FROM[i] >= p) PREFIX_COUNT_FROM[i] -= p; if (PREFIX_COUNT_TO[i] >= p) PREFIX_COUNT_TO[i] -= p; } } void MAKE_COUNT_FROM() { for(int i=1; i<=m; i++) COUNT_FROM[i] = COUNT_TO[m-i+1]; } int main() { TURBO; cin>>n>>m>>p; for(int i=1; i<=m; i++) COUNT_TO[i] = i % p; MAKE_COUNT_FROM(); COUNT_PREFIXES(); ll result = 0; ll diff; for(int pref_len=2; pref_len<=n; pref_len++) { ll all_options = PREFIX_COUNT_FROM[m]; ll prefixowa_baza_pseudokwadratowa = 0; for(int konc=1; konc<=m; konc++) { prefixowa_baza_pseudokwadratowa += PREFIX_COUNT_TO[konc-1]; if (prefixowa_baza_pseudokwadratowa >= p) prefixowa_baza_pseudokwadratowa -= p; result = all_options * konc; result %= p; result -= prefixowa_baza_pseudokwadratowa; diff = PREFIX_COUNT_FROM[m] - PREFIX_COUNT_FROM[konc]; result -= diff * konc; result %= p; result += p; result %= p; COUNT_TO[konc] = result; } MAKE_COUNT_FROM(); COUNT_PREFIXES(); } cout<<PREFIX_COUNT_FROM[m]; return 0; } |
English