結果
問題 | No.1596 Distance Sum in 2D Plane |
ユーザー | emak |
提出日時 | 2021-07-09 22:40:21 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 254 ms / 2,000 ms |
コード長 | 5,776 bytes |
コンパイル時間 | 2,259 ms |
コンパイル使用メモリ | 207,856 KB |
実行使用メモリ | 11,084 KB |
最終ジャッジ日時 | 2024-07-01 17:21:59 |
合計ジャッジ時間 | 7,896 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 173 ms
10,908 KB |
testcase_01 | AC | 173 ms
10,972 KB |
testcase_02 | AC | 249 ms
10,928 KB |
testcase_03 | AC | 252 ms
10,920 KB |
testcase_04 | AC | 253 ms
11,044 KB |
testcase_05 | AC | 254 ms
10,892 KB |
testcase_06 | AC | 251 ms
10,864 KB |
testcase_07 | AC | 248 ms
11,012 KB |
testcase_08 | AC | 248 ms
10,912 KB |
testcase_09 | AC | 250 ms
11,028 KB |
testcase_10 | AC | 251 ms
10,912 KB |
testcase_11 | AC | 229 ms
10,916 KB |
testcase_12 | AC | 231 ms
10,888 KB |
testcase_13 | AC | 230 ms
11,084 KB |
testcase_14 | AC | 173 ms
10,916 KB |
testcase_15 | AC | 173 ms
11,056 KB |
testcase_16 | AC | 172 ms
10,892 KB |
testcase_17 | AC | 172 ms
10,920 KB |
testcase_18 | AC | 172 ms
10,976 KB |
testcase_19 | AC | 174 ms
10,928 KB |
ソースコード
#include<bits/stdc++.h> using namespace std; typedef long long ll; template<typename T> ostream& operator<<(ostream &os, vector<T> &v){ string sep = " "; if(v.size()) os << v[0]; for(int i=1; i<v.size(); i++) os << sep << v[i]; return os; } template<typename T> istream& operator>>(istream &is, vector<T> &v){ for(int i=0; i<v.size(); i++) is >> v[i]; return is; } #ifdef DBG void debug_(){ cout << endl; } template<typename T, typename... Args> void debug_(T&& x, Args&&... xs){ cout << x << " "; debug_(forward<Args>(xs)...); } #define dbg(...) debug_(__VA_ARGS__) #else #define dbg(...) #endif #include<bits/stdc++.h> // Extended Euclid's greatest common divisor algorithm // Find (x, y) // where // - a*x + b*y = gcd(a, b)$ long long ext_gcd(long long a, long long b, long long &x, long long &y){ if(b == 0){ x = 1; y = 0; return a; } long long nx, ny; long long g = ext_gcd(b, a%b, nx, ny); x = ny; y = nx - a / b * ny; return g; } template<long long m=1000000007> struct modint { typedef long long ll; ll x; static constexpr ll mod() { return m; } constexpr modint(ll x=0): x((m+x%m)%m) {} modint<m> operator-() const { return modint(m-x); } modint<m>& operator+=(const modint<m> o) { x=(x+o.x)%m; return *this; } modint<m>& operator+=(const ll o) { return (*this)+=modint(o); } modint<m>& operator-=(const modint<m> o) { return (*this)+=(-o); } modint<m>& operator-=(const ll o) { return (*this)-=modint(o); } modint<m>& operator*=(const modint<m> o) { x = x*o.x%m; return *this; } modint<m>& operator*=(const ll o) { return (*this)*=modint(o); } modint<m>& operator/=(const modint<m> o) { return (*this)*=o.inv(); } modint<m>& operator/=(const ll o) { return (*this)/=modint(o); } friend modint<m> operator+(modint<m> l, const modint<m> r) { l+=r; return l; } friend modint<m> operator+(modint<m> l, const ll r) { l+=r; return l; } friend modint<m> operator+(const ll l, modint<m> r) { r+=l; return r; } friend modint<m> operator-(modint<m> l, const modint<m> r) { l-=r; return l; } friend modint<m> operator-(modint<m> l, const ll r) { l-=r; return l; } friend modint<m> operator-(const ll l, modint<m> r) { r*=-1; r+=l; return r; } friend modint<m> operator*(modint<m> l, const modint<m> r) { l*=r; return l; } friend modint<m> operator*(modint<m> l, const ll r) { l*=r; return l; } friend modint<m> operator*(const ll l, modint<m> r) { r*=l; return r; } friend modint<m> operator/(modint<m> l, const modint<m> r) { l/=r; return l; } friend modint<m> operator/(modint<m> l, const ll r) { l/=r; return l; } friend modint<m> operator/(const ll l, const modint<m> r) { return modint(l)/r; } bool operator==(const modint<m> o) const { return x==o.x; } bool operator!=(const modint<m> o) const { return x!=o.x; } friend bool operator==(const ll l, const modint<m> r) { return modint<m>(l) == r; } friend bool operator!=(const ll l, const modint<m> r) { return modint<m>(l) != r; } friend std::ostream& operator<<(std::ostream &os, const modint<m> x) { return os << x.x; } modint<m> pow(ll k) const { if(k==0) return modint<m>(1); if(k%2) return pow(k-1)*x; modint<m> z = pow(k/2); return z*z; } modint<m> inv() const { ll y,z; ext_gcd(x, m, y, z); return modint<m>(y); } }; using mint = modint<>; template<typename mint = mint> struct Comb { typedef long long ll; const ll m = mint::mod(); std::vector<mint> fact, fact_inv; Comb(int n_max=2000005) { fact.assign(n_max, 0); fact_inv.assign(n_max, 0); fact[0] = 1; fact_inv[0] = 1; for(int i=1; i<std::min((ll)n_max, m); i++){ fact[i] = fact[i-1] * i; fact_inv[i] = fact[i].inv(); } } mint operator() (ll n, ll k) const { if(n < m){ return fact[n] * fact_inv[k] * fact_inv[n-k]; } else { return comb_ext(n, k); } } // Modular factorial of n, also counting p's appearance e // n! = a * p^e // return: a % p // n! = n * (n-1) * ... * (k*p+1) * // (k*p) * (k*p-1) * ... ((k-1)*p+1) * // ... // p * (p-1) * ... * 2 * 1 (k = floor(n/p)) // = (n%p) * ... * 1 * // (k*p) * (p-1) * ... * 1 * // p * (p-1) * ... * 1 (mod p, preserving p's multiples) // = (n%p)! * p^k * k! * (p-1)^k // = (n%p)! * p^k * k! * (p-1)^(k%2) // // From the facts: // (p-1)! = p-1 (mod p) (c.f. Willson's theorem) // (p-2)**2 = 1 (mod p) mint fact_ext(ll n, ll &e) const { if(n == 0){ e = 0; return mint(1); } mint na = fact_ext(n/m, e); e += n/m; mint a = na * fact[n%m]; if((n/m)%2) a = a * (m-1); return a; } // Modular combination (n, m) given module p // (n, m) = n!/(n-m)!m! // = (a_n * p^(e_n)) / ((a_{n-m} * p^(e_{n-m}) * (a_m * p^e_m)) // = a_n / (a_{n-m} * a_m) * p^(e_n - e_{n-m} - e_m) mint comb_ext (ll n, ll k) const { ll e1,e2,e3; mint a1 = fact_ext(n, e1); mint a2 = fact_ext(k, e2); mint a3 = fact_ext(n-k, e3); if(e1 > e2+e3) return 0; else return a1*(a2*a3).inv(); } }; int main() { ios_base::sync_with_stdio(false); cout << setprecision(20) << fixed; Comb c(500000); int n, m; cin >> n >> m; mint ans = 2*n * c(2*n, n); for(int i=0; i<m; i++){ int t, x, y; cin >> t >> x >> y; if(t == 1){ ans -= c(x+y, x) * c(n-x-1+n-y, n-y); } else { ans -= c(x+y, x) * c(n-x+n-y-1, n-x); } } cout << ans << endl; return 0; }