Language: C++

#include <bits/stdc++.h>
#define endl '\n'

using namespace std;
template<class T, class T2> inline void chkmax(T &x, const T2 &y) { if(x < y) x = y; }
template<class T, class T2> inline void chkmin(T &x, const T2 &y) { if(x > y) x = y; }
const int MAXN = (1 << 21);
const int mod = (int)1e9 + 7;
const double PI = acos(-1.0);
const int BK = 100;
const int CK = 5;

inline void addmod(int& x, int y, int mod) { (x += y) >= mod && (x -= mod); }
inline int mulmod(int x, int y, int mod) { return x * 1ll * y % mod; }

struct complex_base
{
	double x, y;
	complex_base(double _x = 0, double _y = 0) { x = _x; y = _y; }
	friend complex_base operator-(const complex_base &a, const complex_base &b) { return complex_base(a.x - b.x, a.y - b.y); }
	friend complex_base operator+(const complex_base &a, const complex_base &b) { return complex_base(a.x + b.x, a.y + b.y); }
	friend complex_base operator*(const complex_base &a, const complex_base &b) { return complex_base(a.x * b.x - a.y * b.y, a.y * b.x + b.y * a.x); }
	friend void operator/=(complex_base &a, const double &P) { a.x /= P; a.y /= P; }
};

int bit_rev[MAXN];

void fft(complex_base *a, int lg)
{
	int n = (1 << lg);
	for(int i = 1; i < n; i++)
	{
		bit_rev[i] = (bit_rev[i >> 1] >> 1) | ((i & 1) << (lg - 1));
		if(bit_rev[i] < i) swap(a[i], a[bit_rev[i]]);
	}

	for(int len = 2; len <= n; len <<= 1)
	{
		long double ang = 2 * PI / len;
		complex_base w(1, 0), wn(cosl(ang), sinl(ang));
		for(int j = 0; j < (len >> 1); j++, w = w * wn)
			for(int i = 0; i < n; i += len)
			{
				complex_base u = a[i + j], v = w * a[i + j + (len >> 1)];
				a[i + j] = u + v;
				a[i + j + (len >> 1)] = u - v;
			}
	}
}

void inv_fft(complex_base *a, int lg)
{
	int n = (1 << lg);
	for(int i = 1; i < n; i++)
	{
		bit_rev[i] = (bit_rev[i >> 1] >> 1) | ((i & 1) << (lg - 1));
		if(bit_rev[i] < i) swap(a[i], a[bit_rev[i]]);
	}

	for(int len = 2; len <= n; len <<= 1)
	{
		long double ang = -2 * PI / len;
		complex_base w(1, 0), wn(cosl(ang), sinl(ang));

		for(int j = 0; j < (len >> 1); j++, w = w * wn)
			for(int i = 0; i < n; i += len)
			{
				complex_base u = a[i + j], v = w * a[i + j + (len >> 1)];
				a[i + j] = u + v;
				a[i + j + (len >> 1)] = u - v;
			}
	}

	for(int i = 0; i < n; i++)
		a[i] /= n;
}

complex_base A[MAXN], B[MAXN];

vector<int> mult(const vector<int> &a, const vector<int> &b)
{
	if(a.size() * b.size() <= 128)
	{
		vector<int> ans(a.size() + b.size(), 0);
		for(int i = 0; i < (int)a.size(); i++)
			for(int j = 0; j < (int)b.size(); j++)
				ans[i + j] = (ans[i + j] + a[i] * 1ll * b[j]) % mod;

		return ans;
	}

	int lg = 0; while((1 << lg) < (int)(a.size() + b.size())) ++lg;
	for(int i = 0; i < (1 << lg); i++) A[i] = B[i] = complex_base(0, 0);
	for(int i = 0; i < (int)a.size(); i++) A[i] = complex_base(a[i], 0);
	for(int i = 0; i < (int)b.size(); i++) B[i] = complex_base(b[i], 0);
 
	fft(A, lg); fft(B, lg);
	for(int i = 0; i < (1 << lg); i++)
		A[i] = A[i] * B[i];
	inv_fft(A, lg);

	vector<int> ans(a.size() + b.size(), 0);
	for(int i = 0; i < (int)ans.size(); i++)
		ans[i] = (int64_t)(A[i].x + 0.5) % mod;

	return ans;
}

vector<complex_base> to_fft(const vector<complex_base> &a, int lg)
{
	for(int i = 0; i < (1 << lg); i++) A[i] = complex_base(0, 0);
	for(int i = 0; i < (int)a.size(); i++) A[i] = a[i];
	fft(A, lg);

	vector<complex_base> ret(1 << lg, 0);
	for(int i = 0; i < (1 << lg); i++)
		ret[i] = A[i];

	return ret;
}

vector<complex_base> to_inv_fft(const vector<complex_base> &a, int lg)
{
	for(int i = 0; i < (1 << lg); i++) A[i] = complex_base(0, 0);
	for(int i = 0; i < (int)a.size(); i++) A[i] = a[i];
	inv_fft(A, lg);

	vector<complex_base> ret(1 << lg, 0);
	for(int i = 0; i < (1 << lg); i++)
		ret[i] = A[i];

	return ret;
}

vector<int> mult_mod(const vector<int> &a, const vector<int> &b)
{
	/// Thanks pavel.savchenkov

	// a = a0 + sqrt(MOD) * a1
	// a = a0 + base * a1
	int base = (int)sqrtl(mod);

	vector<int> a0(a.size()), a1(a.size());
	for(int i = 0; i < (int)a.size(); i++) 
	{
		a0[i] = a[i] % base;
		a1[i] = a[i] / base;
	}

	vector<int> b0(b.size()), b1(b.size());
	for(int i = 0; i < (int)b.size(); i++)
	{
		b0[i] = b[i] % base;
		b1[i] = b[i] / base;
	}

	vector<int> a01 = a0;
	for(int i = 0; i < (int)a.size(); i++) 
		addmod(a01[i], a1[i], mod);  	

	vector<int> b01 = b0;
	for(int i = 0; i < (int)b.size(); i++) 
		addmod(b01[i], b1[i], mod);

	vector<int> C = mult(a01, b01);  // 1

	vector<int> a0b0 = mult(a0, b0); // 2
	vector<int> a1b1 = mult(a1, b1); // 3

	vector<int> mid = C;
	for(int i = 0; i < (int)mid.size(); i++) 
	{
		addmod(mid[i], -a0b0[i] + mod, mod);
		addmod(mid[i], -a1b1[i] + mod, mod);
	}

	vector<int> res = a0b0;
	for(int i = 0; i < (int)res.size(); i++)
		addmod(res[i], mulmod(base, mid[i], mod), mod);

	base = mulmod(base, base, mod);
	for(int i = 0; i < (int)res.size(); i++)
		addmod(res[i], mulmod(base, a1b1[i], mod), mod);

	return res;
}


#define mp make_pair
#define sz(C) ((int) (C).size())
#define forn(i, n) for (int i = 0; i < (int) n; ++i)
 
typedef vector <int> vi;
 
using ld = double;
using ll = int64_t;
 

const ll MOD = mod;

namespace FFT {
  struct cd {
    ld a, b;
 
    cd(ld a, ld b) : a(a), b(b) {}
 
    cd(ld x = 0) : a(x), b(0) {}
 
    ld real() const {
      return a;
    }
 
    void operator += (const cd& other) {
      a += other.a;
      b += other.b;
    }
 
    void operator -= (const cd& other) {
      a -= other.a;
      b -= other.b;
    }
 
    void operator *= (const cd& other) {
      tie(a, b) = mp(a * other.a - b * other.b, a * other.b + b * other.a);
    }
 
    friend cd operator * (const cd& x, const cd& y) {
      cd r = x;
      r *= y;
      return r;
    }
 
    friend cd operator + (const cd& x, const cd& y) {
      cd r = x;
      r += y;
      return r;
    }
 
    friend cd operator - (const cd& x, const cd& y) {
      cd r = x;
      r -= y;
      return r;
    }
 
    void operator /= (ld c) {
      a /= c;
      b /= c;
    }
  };
 
  typedef vector<cd> vcd;
 
  const int LOG = 20;
  const int N = 1 << LOG;
 
  int rev[N];
  cd root_[N];
 
  inline cd root(int k, int n) {
    return root_[k * (N / n)];
  }
 
  void precalc() {
    rev[0] = 0;
    int hb = -1;
    for (int i = 1; i < N; ++i) {
      if  ((i & (i - 1)) == 0) {
        ++hb;
      }
      rev[i] = rev[i ^ (1 << hb)] | (1 << (LOG - hb - 1));
    }
 
    forn(i, N) {
      ld ang = PI * i * 2.0 / N;
      root_[i] = cd(cosl(ang), sinl(ang));
    }
  }
 
  void fft_rec(cd* a, int n) {
    if  (n == 1) {
      return;
    }
 
    fft_rec(a, n / 2);
    fft_rec(a + n / 2, n / 2);
 
    forn(k, n / 2) {
      cd w = root(k, n);
      cd x = a[k];
      cd y = w * a[k + n / 2];
      a[k] = x + y;
      a[k + n / 2] = x - y;
    }
  }
 
  void fft(vcd& a) {
    int n = sz(a);
    vcd na(n, cd(0, 0));
    forn(i, n) na[i] = a[rev[i]];
    na.swap(a);
 
    fft_rec(&a[0], n);
  }
 
  void fft_inv(vcd& a) {
    fft(a);
    int n = sz(a);
    reverse(a.begin() + 1, a.end());
    forn(i, n) {
      a[i] /= n;
    }
  }
 
  vi mult(const vi& a, const vi& b) {
    //    TimeStamp t("mult");
    vcd A(N, cd(0, 0));
    vcd B(N, cd(0, 0));
    forn(i, sz(a)) A[i] = a[i];
    forn(i, sz(b)) B[i] = b[i];
 
    fft(A);
    fft(B);
 
    forn(i, N) A[i] *= B[i];
 
    fft_inv(A);
 
    vi c(N, 0);
    forn(i, N) c[i] = ((ll) (A[i].real() + 0.5)) % MOD;
 
    return c;
  }
 
  vi multmod(const vi& a, const vi& b) {
    // a = a0 + sqrt(MOD) * a1
    // a = a0 + base * a1
    int base = (int) sqrtl(MOD);
 
    vi a0(sz(a)), a1(sz(a));
    forn(i, sz(a)) {
      a0[i] = a[i] % base;
      a1[i] = a[i] / base;
      assert(a[i] == a0[i] + base * a1[i]);
    }
 
    vi b0(sz(b)), b1(sz(b));
    forn(i, sz(b)) {
      b0[i] = b[i] % base;
      b1[i] = b[i] / base;
      assert(b[i] == b0[i] + base * b1[i]);
    }
 
    vi a01 = a0;
    forn(i, sz(a)) {
      addmod(a01[i], a1[i], MOD);
    }
 
    vi b01 = b0;
    forn(i, sz(b)) {
      addmod(b01[i], b1[i], MOD);
    }
 
    vi C = mult(a01, b01);  // 1
 
    vi a0b0 = mult(a0, b0); // 2
    vi a1b1 = mult(a1, b1); // 3
 
    vi mid = C;
    forn(i, N) {
      addmod(mid[i], -a0b0[i] + MOD, MOD);
      addmod(mid[i], -a1b1[i] + MOD, MOD);
    }
 
    vi res = a0b0;
    forn(i, N) {
      addmod(res[i], mulmod(base, mid[i], MOD), MOD);
    }
 
    base = mulmod(base, base, MOD);
    forn(i, N) {
      addmod(res[i], mulmod(base, a1b1[i], MOD), MOD);
    }
 
    return res;
  }
};

int n, m, k;

void read()
{
	cin >> n >> m >> k;
}

vector<int> p1, p2, pw3;

int pw(int x, int p)
{
	int ret = 1;
	while(p)
	{
		if(p & 1) ret = (ret * 1ll * x) % mod;
		x = (x * 1ll * x) % mod;
		p >>= 1;
	}

	return ret;
}

int fact[MAXN], inv_fact[MAXN];
int comb(int n, int k) { if(n < 0 || k < 0 || n < k) return 0; return (((fact[n] * 1ll * inv_fact[n - k]) % mod) * 1ll * inv_fact[k]) % mod; }

/*   SUM C(n + i - 1, i) * C(n + i - 1 + j, j)   */
/*   SUM C(n + i - 1, i) * fact[n + i - 1 + j] / (fact[j] * fact[n + i - 1])    */


void solve()
{	
	pw3.assign(n + m + k + 1, 0);
	p1.assign(m + 1, 0);
	p2.assign(k + 1, 0);
	pw3[0] = 1; for(int i = 1; i <= m + k + n; i++) pw3[i] = (3ll * pw3[i - 1]) % mod;
	fact[0] = 1; for(int i = 1; i <= m + k + n; i++) fact[i] = (fact[i - 1] * 1ll * i) % mod;
	inv_fact[m + k + n] = pw(fact[m + k + n], mod - 2); for(int i = n + k + m - 1; i >= 0; i--) inv_fact[i] = (inv_fact[i + 1] * 1ll * (i + 1)) % mod; 

	for(int i = 0; i <= m; i++) p1[i] = (comb(n + i - 1, i) * 1ll * inv_fact[n + i - 1]) % mod;
	for(int i = 0; i <= k; i++) p2[i] = inv_fact[i];

	vector<int> ret = mult_mod(p1, p2);
	
	int answer = 0;
	for(int i = 0; i < (int)ret.size(); i++)
	{
		if(m + k - i < 0) break;
		int curr = (ret[i] * 1ll * pw3[m + k - i]) % mod;
		curr = (curr * 1ll * fact[n - 1 + i]) % mod;
		addmod(answer, curr, mod);
	}

	cout << answer << endl;
}

int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	read();
	solve();
	return 0;
}

v

Compiler output:
a.cc:453:1: error: 'v' does not name a type; did you mean 'vi'?
  453 | v
      | ^
      | vi