結果
問題 | No.578 3 x N グリッド上のサイクルのサイズ(easy) |
ユーザー | yosupot |
提出日時 | 2017-10-13 23:21:29 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 2 ms / 2,000 ms |
コード長 | 12,468 bytes |
コンパイル時間 | 2,110 ms |
コンパイル使用メモリ | 133,796 KB |
実行使用メモリ | 5,248 KB |
最終ジャッジ日時 | 2024-11-17 11:48:50 |
合計ジャッジ時間 | 3,161 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
5,248 KB |
testcase_01 | AC | 2 ms
5,248 KB |
testcase_02 | AC | 2 ms
5,248 KB |
testcase_03 | AC | 2 ms
5,248 KB |
testcase_04 | AC | 2 ms
5,248 KB |
testcase_05 | AC | 2 ms
5,248 KB |
testcase_06 | AC | 2 ms
5,248 KB |
testcase_07 | AC | 2 ms
5,248 KB |
testcase_08 | AC | 2 ms
5,248 KB |
testcase_09 | AC | 2 ms
5,248 KB |
testcase_10 | AC | 2 ms
5,248 KB |
testcase_11 | AC | 2 ms
5,248 KB |
testcase_12 | AC | 2 ms
5,248 KB |
testcase_13 | AC | 2 ms
5,248 KB |
testcase_14 | AC | 2 ms
5,248 KB |
testcase_15 | AC | 2 ms
5,248 KB |
testcase_16 | AC | 2 ms
5,248 KB |
testcase_17 | AC | 2 ms
5,248 KB |
testcase_18 | AC | 2 ms
5,248 KB |
testcase_19 | AC | 2 ms
5,248 KB |
testcase_20 | AC | 2 ms
5,248 KB |
testcase_21 | AC | 2 ms
5,248 KB |
testcase_22 | AC | 2 ms
5,248 KB |
testcase_23 | AC | 2 ms
5,248 KB |
testcase_24 | AC | 2 ms
5,248 KB |
testcase_25 | AC | 2 ms
5,248 KB |
testcase_26 | AC | 2 ms
5,248 KB |
testcase_27 | AC | 2 ms
5,248 KB |
testcase_28 | AC | 2 ms
5,248 KB |
testcase_29 | AC | 2 ms
5,248 KB |
testcase_30 | AC | 2 ms
5,248 KB |
testcase_31 | AC | 2 ms
5,248 KB |
testcase_32 | AC | 2 ms
5,248 KB |
testcase_33 | AC | 2 ms
5,248 KB |
testcase_34 | AC | 2 ms
5,248 KB |
testcase_35 | AC | 1 ms
5,248 KB |
testcase_36 | AC | 1 ms
5,248 KB |
testcase_37 | AC | 2 ms
5,248 KB |
testcase_38 | AC | 2 ms
5,248 KB |
testcase_39 | AC | 2 ms
5,248 KB |
testcase_40 | AC | 2 ms
5,248 KB |
testcase_41 | AC | 1 ms
5,248 KB |
testcase_42 | AC | 2 ms
5,248 KB |
testcase_43 | AC | 2 ms
5,248 KB |
testcase_44 | AC | 2 ms
5,248 KB |
testcase_45 | AC | 2 ms
5,248 KB |
testcase_46 | AC | 2 ms
5,248 KB |
testcase_47 | AC | 2 ms
5,248 KB |
testcase_48 | AC | 2 ms
5,248 KB |
testcase_49 | AC | 2 ms
5,248 KB |
ソースコード
#include <iostream> #include <iomanip> #include <cstdio> #include <cstdlib> #include <cstring> #include <cassert> #include <algorithm> #include <numeric> #include <random> #include <vector> #include <array> #include <bitset> #include <queue> #include <set> #include <unordered_set> #include <map> #include <unordered_map> using namespace std; using uint = unsigned int; using ll = long long; using ull = unsigned long long; constexpr ll TEN(int n) { return (n==0) ? 1 : 10*TEN(n-1); } template<class T> using V = vector<T>; template<class T> using VV = V<V<T>>; struct rng { struct A { int n; const bool operator!=(A r) { return n != r.n; } A& operator++() { n++; return *this; } int operator*() { return n; } }; int l, r; rng(int r) : l(0), r(max(0, r)) {} rng(int l, int r) : l(l), r(max(l, r)) {} A begin() { return A{l}; } A end() { return A{r}; } }; //bit op int bsr(uint x) { return 31 - __builtin_clz(x); } int bsr(ull x) { return 63 - __builtin_clzll(x); } int bsf(uint x) { return __builtin_ctz(x); } int bsf(ull x) { return __builtin_ctzll(x); } template<class T> T pow(T x, ll n, T r) { while (n) { if (n & 1) r *= x; x *= x; n >>= 1; } return r; } template<class T> T pow(T x, ll n) { return pow(x, n, T(1)); } template<uint MD> struct ModInt { uint v; ModInt() : v{0} {} ModInt(ll v) : v{normS(v%MD+MD)} {} explicit operator bool() const {return v != 0;} static uint normS(uint x) {return (x<MD)?x:x-MD;}; static ModInt make(uint x) {ModInt m; m.v = x; return m;} static ModInt inv(const ModInt &x) {return pow(ModInt(x), MD-2);} ModInt operator+(const ModInt &r) const {return make(normS(v+r.v));} ModInt operator-(const ModInt &r) const {return make(normS(v+MD-r.v));} ModInt operator*(const ModInt &r) const {return make(ull(v)*r.v%MD);} ModInt operator/(const ModInt &r) const {return *this*inv(r);} ModInt& operator+=(const ModInt &r) {return *this=*this+r;} ModInt& operator-=(const ModInt &r) {return *this=*this-r;} ModInt& operator*=(const ModInt &r) {return *this=*this*r;} ModInt& operator/=(const ModInt &r) {return *this=*this/r;} }; template<uint MD> string to_string(ModInt<MD> m) {return to_string(m.v);} using Mint = ModInt<TEN(9)+7>; using R = double; struct Pc { R x, y; Pc() : x(0), y(0) {} Pc(R x, R y) : x(x), y(y) {} Pc operator+(const Pc &r) const {return Pc(x+r.x, y+r.y);} Pc operator-(const Pc &r) const {return Pc(x-r.x, y-r.y);} Pc operator*(const Pc &r) const {return Pc(x*r.x-y*r.y, x*r.y+y*r.x);} Pc operator*(const R &r) const {return Pc(x*r, y*r);} Pc& operator+=(const Pc &r) {return *this=*this+r;} Pc& operator-=(const Pc &r) {return *this=*this-r;} Pc& operator*=(const Pc &r) {return *this=*this*r;} Pc& operator*=(const R &r) {return *this=*this*r;} static Pc polar(R r, R th) {return Pc(cos(th)*r, sin(th)*r);} }; const R PI = 4*atan(R(1)); void fft(bool type, V<Pc> &c) { static V<Pc> buf[30]; int N = int(c.size()); int s = bsr(uint(N)); assert(1<<s == N); if (!buf[s].size()) { buf[s] = V<Pc>(N); for (int i = 0; i < N; i++) { buf[s][i] = Pc::polar(1, i*2*PI/N); } } V<Pc> a = c, b(N); for (int i = 1; i <= s; i++) { int W = 1<<(s-i); //変更後の幅W for (int y = 0; y < N/2; y += W) { Pc now = buf[s][y]; if (type) now.y *= -1; for (int x = 0; x < W; x++) { auto l = a[y<<1 | x]; auto r = now * a[y<<1 | x | W]; b[y | x] = l+r; b[y | x | N>>1] = l-r; } } swap(a, b); } c = a; } template<class Mint> V<Mint> multiply(V<Mint> x, V<Mint> y) { constexpr int B = 3, SHIFT = 10; int S = x.size()+y.size()-1; int N = 2<<bsr(uint(S-1)); V<Pc> a[B], b[B]; for (int fe = 0; fe < B; fe++) { a[fe] = V<Pc>(N); b[fe] = V<Pc>(N); V<Pc> c(N); for (int i = 0; i < int(x.size()); i++) { c[i].x = (x[i].v >> (fe*SHIFT)) & ((1<<SHIFT)-1); } for (int i = 0; i < int(y.size()); i++) { c[i].y = (y[i].v >> (fe*SHIFT)) & ((1<<SHIFT)-1); } fft(false, c); for (int i = 0; i < N; i++) { c[i] *= 0.5; } for (int i = 0; i < N; i++) { int j = (N-i)%N; a[fe][i] = Pc(c[i].x+c[j].x, c[i].y-c[j].y); b[fe][i] = Pc(c[i].y+c[j].y, -c[i].x+c[j].x); } } V<Mint> z(S); V<Pc> c[B]; for (int fe = 0; fe < B; fe++) { c[fe] = V<Pc>(N); } for (int af = 0; af < B; af++) { for (int bf = 0; bf < B; bf++) { int cf = (af+bf)%B; for (int i = 0; i < N; i++) { if (af+bf<B) { c[cf][i] += a[af][i]*b[bf][i]; } else { c[cf][i] += a[af][i]*b[bf][i]*Pc(0, 1); } } } } for (int fe = 0; fe < B; fe++) { fft(true, c[fe]); } Mint base = 1; for (int fe = 0; fe < 2*B-1; fe++) { for (int i = 0; i < S; i++) { if (fe < B) { c[fe][i].x *= 1.0/N; z[i] += Mint(ll(round(c[fe][i].x)))*base; } else { c[fe-B][i].y *= 1.0/N; z[i] += Mint(ll(round(c[fe-B][i].y)))*base; } } base *= 1<<SHIFT; } return z; } template<class D> struct Poly { V<D> v; int size() const {return int(v.size());} Poly(int N = 0) : v(V<D>(N)) {} Poly(const V<D> &v) : v(v) {shrink();} Poly& shrink() {while (v.size() && !v.back()) v.pop_back(); return *this;} D freq(int p) const { return (p < size()) ? v[p] : D(0); } Poly operator+(const Poly &r) const { int N = size(), M = r.size(); V<D> res(max(N, M)); for (int i = 0; i < max(N, M); i++) res[i] = freq(i)+r.freq(i); return Poly(res); } Poly operator-(const Poly &r) const { int N = size(), M = r.size(); V<D> res(max(N, M)); for (int i = 0; i < max(N, M); i++) res[i] = freq(i)-r.freq(i); return Poly(res); } Poly operator*(const Poly &r) const { int N = size(), M = r.size(); if (min(N, M) == 0) return Poly(); assert(N+M-1 >= 0); V<D> res = multiply(v, r.v); return Poly(res); } Poly operator*(const D &r) const { V<D> res(size()); for (int i = 0; i < size(); i++) res[i] = v[i]*r; return Poly(res); } Poly& operator+=(const Poly &r) {return *this = *this+r;} Poly& operator-=(const Poly &r) {return *this = *this-r;} Poly& operator*=(const Poly &r) {return *this = *this*r;} Poly& operator*=(const D &r) {return *this = *this*r;} Poly operator<<(const int n) const { assert(n >= 0); V<D> res(size()+n); for (int i = 0; i < size(); i++) { res[i+n] = v[i]; } return Poly(res); } Poly operator>>(const int n) const { assert(n >= 0); if (size() <= n) return Poly(); V<D> res(size()-n); for (int i = n; i < size(); i++) { res[i-n] = v[i]; } return Poly(res); } // x % y Poly rem(const Poly &y) const { return *this - y * div(y); } Poly rem_inv(const Poly &y, const Poly &ny, int B) const { return *this - y * div_inv(ny, B); } Poly div(const Poly &y) const { int B = max(size(), y.size()); return div_inv(y.inv(B), B); } Poly div_inv(const Poly &ny, int B) const { return (*this*ny)>>(B-1); } // this * this.inv() = x^n + r(x) (size()) Poly strip(int n) const { V<D> res = v; res.resize(min(n, size())); return Poly(res); } Poly rev(int n = -1) const { V<D> res = v; if (n != -1) res.resize(n); reverse(begin(res), end(res)); return Poly(res); } // f * f.inv() = x^B + r(x) (B >= n) Poly inv(int n) const { int N = size(); assert(N >= 1); assert(n >= N-1); Poly c = rev(); Poly d = Poly(V<D>({D(1)/c.freq(0)})); int i; for (i = 1; i+N-2 < n; i *= 2) { auto u = V<D>({2}); d = (d * (Poly(V<D>{2})-c*d)).strip(2*i); } return d.rev(n+1-N); } }; template<class D> string to_string(const Poly<D> &p) { if (p.size() == 0) return "0"; string s = ""; for (int i = 0; i < p.size(); i++) { if (p.v[i]) { s += to_string(p.v[i])+"x^"+to_string(i); if (i != p.size()-1) s += "+"; } } return s; } // x^n % mod template<class D> Poly<D> nth_mod(ll n, const Poly<D> &mod) { int B = mod.size() * 2 - 1; Poly<D> mod_inv = mod.inv(B); Poly<D> p = V<D>{Mint(1)}; int m = (!n) ? -1 : bsr(ull(n)); for (int i = m; i >= 0; i--) { if (n & (1LL<<i)) { // += 1 p = (p<<1).rem_inv(mod, mod_inv, B); } if (i) { // *= 2 p = (p*p).rem_inv(mod, mod_inv, B); } } return p; } template<class D> Poly<D> berlekamp_massey(const V<D> &s) { int N = int(s.size()); V<D> b = {D(-1)}, c = {D(-1)}; D y = D(1); for (int ed = 1; ed <= N; ed++) { int L = int(c.size()), M = int(b.size()); D x = 0; for (int i = 0; i < L; i++) { x += c[i]*s[ed-L+i]; } b.push_back(0); M++; if (!x) { continue; } D freq = x/y; if (L < M) { //use b auto tmp = c; c.insert(begin(c), M-L, D(0)); for (int i = 0; i < M; i++) { c[M-1-i] -= freq*b[M-1-i]; } b = tmp; y = x; } else { //use c for (int i = 0; i < M; i++) { c[L-1-i] -= freq*b[M-1-i]; } } } return Poly<D>(c); } using Pol = Poly<Mint>; int main() { cin.tie(0); ios::sync_with_stdio(false); cout << setprecision(20); V<Mint> po = { 0, 32, 316, 2292, 14422, 84744, 479004, 2638328, 14258574, 75940592, 399782668, 84795558, 786749020, 442043859, 352536615, 76576421, 744912747, 420315017, 25759333, 562730793, 424899366, 153177921, 250747498, 306910436, 324829483, 572545341, 104022619, 226237183, 421453002, 754280938, 291624319, 60437277, 297658752, 677142927, 63550828, 801541292, 683008492, 650348, 519624175, 715484025, 724658778, 152363657, 280344328, 892278238, 206785631, 227202296, 788486407, 392284243, 927772200, 781378846, 881515964, 905982211, 674841192, 139044658, 711210295, 384364637, 137653614, 441363040, 812818651, 929556368, 494420762, 802527485, 700803632, 461521718, 152786116, 688977792, 48724029, 642700933, 15567410, 246397043, 859581827, 685250826, 120226158, 551687712, 987163282, 422276494, 570671107, 813070470, 429968009, 849487586, 453150672, 606112895, 921636591, 961537190, 68995663, 873642098, 377371441, 101407285, 187434129, 180415383, 920712750, 544594592, 402649575, 549811430, 619506771, 426917748, 274013175, 615469131, 800944525, 925880089, }; auto pol = Pol(po); auto v = berlekamp_massey(po); // cout << to_string(v) << endl; ll x; cin >> x; auto z = nth_mod(x, v); Mint sm = 0; for (int i: rng(int(v.size()))) { sm += po[i] * z.freq(i); } // cout << to_string(z) << endl; cout << sm.v << endl; return 0; }