题解 P5481 【[BJOI2015] 糖果】
Rorschachindark · · 题解
糖果
思路
#include <bits/stdc++.h>
using namespace std;
#define Int register int
#define ll long long
#define MAXN 100005
int tot;
int prime[MAXN];
bool vis[MAXN];
void Prime (int n)
{
for (Int i = 2;i <= n;++ i)
{
if (!vis[i]) prime[++ tot] = i;
for (Int j = 1;j <= tot && (int)i * prime[j] <= n;++ j)
{
vis[i * prime[j]] = 1;
if (i % prime[j] == 0) break;
}
}
}
ll up[MAXN],Index[MAXN];
int n,m,k,p;
int read ()
{
int x = 0;char c = getchar();int f = 1;
while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}
while (c >= '0' && c <= '9'){x = (x << 3) + (x << 1) + c - '0';c = getchar();}
return x * f;
}
void write (int x)
{
if (x < 0){x = -x;putchar ('-');}
if (x > 9) write (x / 10);
putchar (x % 10 + '0');
}
signed main()
{
n = read (),m = read (),k = read (),p = read ();
if (!p) return puts ("0"),0;
for (Int i = 1;i <= m;++ i) up[i] = m + k - i;
Prime (m);
for (Int i = 1;i <= tot && prime[i] <= m;++ i)
{
for (Int j = prime[i];j <= m;j *= prime[i])
Index[i] += m / j;
}
for (Int i = 1;i <= tot;++ i)
{
int s = m + k - 1 - (m + k - 1) % prime[i];
for (Int j = m + k - s;j <= m;j += prime[i])
{
while (Index[i] && up[j] % prime[i] == 0) Index[i] --,up[j] /= prime[i];
if (!Index[i]) break;
}
}
int s = 1,sum = 1;
for (Int i = 1;i <= m;++ i) s = (ll)s * up[i] % p;
for (Int i = 1;i <= n;++ i) sum = (ll)sum * (s - i + 1) % p;
write (sum),putchar ('\n');
return 0;
}