Problem p02625 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <bits/stdc++.h>

using namespace std;

const int N = 5e5 + 5, M = 1e6 + 6, OO = 0x3f3f3f3f;

typedef long long ll;
ll MOD = 1e9 + 7;

ll power(ll a, ll b) { // Fast Power O(log(b))
  if (!b)
    return 1;
  ll t = power(a, b >> 1);
  return t * t * (b & 1 ? a : 1);
}

unsigned long long power(ll a, ll b, ll m) { // Fast power with mod;
  if (!b)
    return 1;
  ll t = power(a, b >> 1, m) % m;
  return ((t * t) % m * (b & 1 ? a : 1) % m) % m;
}

ll gcd(ll a, ll b) {
  if (!b)
    return a;
  return gcd(b, a % b);
}

ll lcm(ll a, ll b) {
  //    return a*b/__gcd(a, b);
  return a / __gcd(a, b) * b;
}

ll mod(ll a, ll b) { // If you are modding negative values
  return (a % b + b) % b;
}

ll floor(ll a, ll b) { // Flooring with negative values
  return (a - mod(a, b)) / b;
}

vector<ll> getDivisors(ll n) { // O(sqrt(n))
  vector<ll> ret;
  ll i;
  for (i = 1; i < n / i; ++i) {
    if (n % i == 0) {
      ret.push_back(i);
      ret.push_back(n / i);
    }
  }
  if (i * i == n)
    ret.push_back(i);
  return ret;
}

vector<ll> getMultiples(ll x, ll n) {
  vector<ll> ret;
  for (ll m = x; m <= n; m += x)
    ret.push_back(m);
  return ret;
}

bool isPrime(ll n) { // O(sqrt(n))
  if (n < 2)
    return 0; //{0, 1}
  for (ll i = 2; i <= n / i; ++i)
    if (n % i == 0)
      return 0;
  return 1;
}

// bool is_prime[N];
bitset<N> is_prime;
void sieve() { // O(N*log(log(n))) ~= O(N)
  // fill(is_prime, is_prime+N, 1);       //with arrays
  is_prime.set(); // fills with 1
  is_prime[0] = is_prime[1] = 0;
  for (ll p = 2; p <= N / p; ++p)
    if (is_prime[p])
      for (ll m = p * p; m < N; m += p)
        is_prime[m] = 0;
}

vector<pair<ll, ll>> factorize(ll n) {
  vector<pair<ll, ll>> ret;
  for (ll p = 2; p <= n / p; ++p) {
    int e = 0;
    while (n % p == 0) {
      n /= p;
      ++e;
    }
    if (e)
      ret.push_back({p, e});
  }
  if (n > 1)
    ret.push_back({n, 1});
  return ret;
}

unsigned long long fac[N];
unsigned long long modInverse(ll n, ll p) { return power(n, p - 2, p); }

unsigned long long nCrModPFermat(ll n, ll r, ll p) {
  // Base case
  if (r == 0 || r == n)
    return 1;

  // Fill factorial array so that we
  // can find all factorial of r, n
  // and n-r

  return (fac[n] * modInverse(fac[r], p) % p * modInverse(fac[n - r], p) % p) %
         p;
}
unsigned long long nprMod(ll n, ll r, ll p) {
  if (n == r)
    return fac[n];
  if (r == 0)
    return 1;
  return (fac[n] * modInverse(fac[n - r], p) % p) % p;

  // cout<<n<<" "<<r<<endl;
  // cout<<nCrModPFermat(n, r, p)<<" "<<fac[r]<<endl;
  // return (nCrModPFermat(n, r, p) * fac[r]) % MOD;
}

int main() {
  fac[0] = 1;
  for (ll i = 1; i < N; i++)
    fac[i] = (fac[i - 1] % MOD * i % MOD) % MOD;
  unsigned long long n, m, ans = 0;
  scanf("%lld %lld", &n, &m);
  int flag = 1;
  for (int i = 0; i <= n; i++) {
    ll x = nprMod(m - i, n - i, MOD);
    ll tmp = ((nCrModPFermat(n, i, MOD) * nprMod(m, i, MOD)) % MOD) *
             ((x * x) % MOD) % MOD;
    // cout<<tmp<<endl;
    ans = (ans + (tmp * flag) + MOD) % MOD;
    flag *= -1;
  }
  printf("%lld", ans % MOD);

  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

const int N = 5e5 + 5, M = 1e6 + 6, OO = 0x3f3f3f3f;

typedef long long ll;
ll MOD = 1e9 + 7;

ll power(ll a, ll b) { // Fast Power O(log(b))
  if (!b)
    return 1;
  ll t = power(a, b >> 1);
  return t * t * (b & 1 ? a : 1);
}

unsigned long long power(ll a, ll b, ll m) { // Fast power with mod;
  if (!b)
    return 1;
  ll t = power(a, b >> 1, m) % m;
  return ((t * t) % m * (b & 1 ? a : 1) % m) % m;
}

ll gcd(ll a, ll b) {
  if (!b)
    return a;
  return gcd(b, a % b);
}

ll lcm(ll a, ll b) {
  //    return a*b/__gcd(a, b);
  return a / __gcd(a, b) * b;
}

ll mod(ll a, ll b) { // If you are modding negative values
  return (a % b + b) % b;
}

ll floor(ll a, ll b) { // Flooring with negative values
  return (a - mod(a, b)) / b;
}

vector<ll> getDivisors(ll n) { // O(sqrt(n))
  vector<ll> ret;
  ll i;
  for (i = 1; i < n / i; ++i) {
    if (n % i == 0) {
      ret.push_back(i);
      ret.push_back(n / i);
    }
  }
  if (i * i == n)
    ret.push_back(i);
  return ret;
}

vector<ll> getMultiples(ll x, ll n) {
  vector<ll> ret;
  for (ll m = x; m <= n; m += x)
    ret.push_back(m);
  return ret;
}

bool isPrime(ll n) { // O(sqrt(n))
  if (n < 2)
    return 0; //{0, 1}
  for (ll i = 2; i <= n / i; ++i)
    if (n % i == 0)
      return 0;
  return 1;
}

// bool is_prime[N];
bitset<N> is_prime;
void sieve() { // O(N*log(log(n))) ~= O(N)
  // fill(is_prime, is_prime+N, 1);       //with arrays
  is_prime.set(); // fills with 1
  is_prime[0] = is_prime[1] = 0;
  for (ll p = 2; p <= N / p; ++p)
    if (is_prime[p])
      for (ll m = p * p; m < N; m += p)
        is_prime[m] = 0;
}

vector<pair<ll, ll>> factorize(ll n) {
  vector<pair<ll, ll>> ret;
  for (ll p = 2; p <= n / p; ++p) {
    int e = 0;
    while (n % p == 0) {
      n /= p;
      ++e;
    }
    if (e)
      ret.push_back({p, e});
  }
  if (n > 1)
    ret.push_back({n, 1});
  return ret;
}

unsigned long long fac[N];
unsigned long long modInverse(ll n, ll p) { return power(n, p - 2, p); }

unsigned long long nCrModPFermat(ll n, ll r, ll p) {
  // Base case
  if (r == 0)
    return 1;

  // Fill factorial array so that we
  // can find all factorial of r, n
  // and n-r

  return (fac[n] * modInverse(fac[r], p) % p * modInverse(fac[n - r], p) % p) %
         p;
}
unsigned long long nprMod(ll n, ll r, ll p) {
  // if(n == r)
  //     return fac[N];
  // cout<<n<<" "<<r<<endl;
  // cout<<nCrModPFermat(n, r, p)<<" "<<fac[r]<<endl;
  return (nCrModPFermat(n, r, p) * fac[r]) % MOD;
}

int main() {
  fac[0] = 1;
  for (ll i = 1; i < N; i++)
    fac[i] = (fac[i - 1] % MOD * i % MOD) % MOD;
  unsigned long long n, m, ans = 0;
  scanf("%lld %lld", &n, &m);
  int flag = 1;
  for (int i = 0; i <= n; i++) {

    ll x = nprMod(m - i, n - i, MOD);
    ll tmp = ((nCrModPFermat(n, i, MOD) * nprMod(m, i, MOD)) % MOD) *
             ((x * x) % MOD) % MOD;
    // cout<<tmp<<endl;
    ans = (ans + (tmp * flag) + MOD) % MOD;
    flag *= -1;
  }
  printf("%lld", ans % MOD);

  return 0;
}