結果
問題 | No.510 二次漸化式 |
ユーザー | はむこ |
提出日時 | 2016-09-07 21:50:45 |
言語 | C++11 (gcc 11.4.0) |
結果 |
AC
|
実行時間 | 1,020 ms / 3,000 ms |
コード長 | 6,938 bytes |
コンパイル時間 | 1,800 ms |
コンパイル使用メモリ | 177,468 KB |
実行使用メモリ | 172,800 KB |
最終ジャッジ日時 | 2024-11-15 21:18:25 |
合計ジャッジ時間 | 26,154 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
5,248 KB |
testcase_01 | AC | 1 ms
5,248 KB |
testcase_02 | AC | 412 ms
5,248 KB |
testcase_03 | AC | 412 ms
5,248 KB |
testcase_04 | AC | 413 ms
5,248 KB |
testcase_05 | AC | 412 ms
5,248 KB |
testcase_06 | AC | 619 ms
24,576 KB |
testcase_07 | AC | 623 ms
24,448 KB |
testcase_08 | AC | 623 ms
24,448 KB |
testcase_09 | AC | 620 ms
24,448 KB |
testcase_10 | AC | 179 ms
5,248 KB |
testcase_11 | AC | 180 ms
5,248 KB |
testcase_12 | AC | 179 ms
5,248 KB |
testcase_13 | AC | 183 ms
5,248 KB |
testcase_14 | AC | 180 ms
5,248 KB |
testcase_15 | AC | 181 ms
5,248 KB |
testcase_16 | AC | 572 ms
172,544 KB |
testcase_17 | AC | 569 ms
172,672 KB |
testcase_18 | AC | 569 ms
172,544 KB |
testcase_19 | AC | 569 ms
172,672 KB |
testcase_20 | AC | 571 ms
172,544 KB |
testcase_21 | AC | 570 ms
172,672 KB |
testcase_22 | AC | 568 ms
172,672 KB |
testcase_23 | AC | 948 ms
172,544 KB |
testcase_24 | AC | 949 ms
172,544 KB |
testcase_25 | AC | 950 ms
172,672 KB |
testcase_26 | AC | 958 ms
172,672 KB |
testcase_27 | AC | 952 ms
172,672 KB |
testcase_28 | AC | 951 ms
172,672 KB |
testcase_29 | AC | 955 ms
172,544 KB |
testcase_30 | AC | 950 ms
172,800 KB |
testcase_31 | AC | 1,020 ms
172,544 KB |
testcase_32 | AC | 1,018 ms
172,544 KB |
testcase_33 | AC | 1,019 ms
172,672 KB |
testcase_34 | AC | 812 ms
172,672 KB |
testcase_35 | AC | 678 ms
172,800 KB |
ソースコード
#include <bits/stdc++.h> using namespace std; #define rep(i,n) for(int i = 0; i < n; i++) #define all(x) x.begin(), x.end() #define Min(x) *min_element(all(x)) #define Max(x) *max_element(all(x)) template <typename T, typename U> ostream &operator<<(ostream &o, const pair<T, U> &v) { o << "(" << v.first << ", " << v.second << ")"; return o; } template <typename T> ostream &operator<<(ostream &o, const vector<T> &v) { if (!v.empty()) { o << '['; copy(v.begin(), v.end(), ostream_iterator<T>(o, ", ")); o << "\b\b]"; } return o; } using ll = long long; using ld = long double; using vll = vector<ll>; using vi = vector<int>; typedef pair<ld, ld> P; static const double EPS = 1e-14; static const long long INF = 1e18; #define MAX_N 100005 class Mod { public: int num; int mod; Mod() : Mod(0) {} Mod(long long int n) : Mod(n, 1000000007) {} Mod(long long int n, int m) { mod = m; num = (n % mod + mod) % mod;} Mod(const string &s){ long long int tmp = 0; for(auto &c:s) tmp = (c-'0'+tmp*10) % mod; num = tmp; } Mod(int n) : Mod(static_cast<long long int>(n)) {} operator int() { return num; } void setmod(const int mod) { this->mod = mod; } }; istream &operator>>(istream &is, Mod &x) { long long int n; is >> n; x = n; return is; } ostream &operator<<(ostream &o, const Mod &x) { o << x.num; return o; } Mod operator+(const Mod a, const Mod b) { return Mod((a.num + b.num) % a.mod); } Mod operator+(const long long int a, const Mod b) { return Mod(a) + b; } Mod operator+(const Mod a, const long long int b) { return b + a; } Mod operator++(Mod &a) { return a + Mod(1); } Mod operator-(const Mod a, const Mod b) { return Mod((a.mod + a.num - b.num) % a.mod); } Mod operator-(const long long int a, const Mod b) { return Mod(a) - b; } Mod operator--(Mod &a) { return a - Mod(1); } Mod operator*(const Mod a, const Mod b) { return Mod(((long long)a.num * b.num) % a.mod); } Mod operator*(const long long int a, const Mod b) { return Mod(a)*b; } Mod operator*(const Mod a, const long long int b) { return Mod(b)*a; } Mod operator*(const Mod a, const int b) { return Mod(b)*a; } Mod operator+=(Mod &a, const Mod b) { return a = a + b; } Mod operator+=(long long int &a, const Mod b) { return a = a + b; } Mod operator-=(Mod &a, const Mod b) { return a = a - b; } Mod operator-=(long long int &a, const Mod b) { return a = a - b; } Mod operator*=(Mod &a, const Mod b) { return a = a * b; } Mod operator*=(long long int &a, const Mod b) { return a = a * b; } Mod operator*=(Mod& a, const long long int &b) { return a = a * b; } Mod factorial(const long long n) { if (n < 0) return 0; Mod ret = 1; for (int i = 1; i <= n; i++) { ret *= i; } return ret; } Mod operator^(const Mod a, const long long n) { if (n == 0) return Mod(1); Mod res = (a * a) ^ (n / 2); if (n % 2) res = res * a; return res; } Mod modpowsum(const Mod a, const long long b) { if (b == 0) return 0; if (b % 2 == 1) return modpowsum(a, b - 1) * a + Mod(1); Mod result = modpowsum(a, b / 2); return result * (a ^ (b / 2)) + result; } /*************************************/ // GF(p)の行列演算 /*************************************/ using number = Mod; using arr = vector<number>; using matrix = vector<vector<Mod>>; ostream &operator<<(ostream &o, const arr &v) { rep(i, v.size()) cout << v[i] << " "; cout << endl; return o; } ostream &operator<<(ostream &o, const matrix &v) { rep(i, v.size()) cout << v[i]; return o; } matrix initial_mat(int n) { matrix A(n, arr(n, 0)); A[0][0] = 1; A[1][3] = 1; A[2][3] = 1; A[3][3] = 1; return A; } // O(n^2) // O(n^3) matrix mul(const matrix &A, const matrix &B) { matrix C(A.size(), arr(B[0].size(), 0)); rep(i, C.size()) rep(j, C[i].size()) rep(k, A[i].size()) C[i][j] += A[i][k] * B[k][j]; return C; } struct Pool { int pos; char mem[20000000]; // 20MB Pool(){ free(); } template<class T> T *fetch(size_t n = 1) { T *res = (T*)(mem + pos); pos += sizeof(T)*n; return res; } void free(){ pos = 0; } }; Pool pool; template<class T> class AssosiativeOperator { public: AssosiativeOperator(void) { } T T0; // 単位元 virtual T op(T a, T b) = 0; // 結合二項演算 }; template<class T> class AssosiativeOperatorMatrix : public AssosiativeOperator<T> { public: AssosiativeOperatorMatrix(void) { AssosiativeOperator<T>::T0 = initial_mat(4); } virtual T op(T a, T b) { return mul(a, b); } }; template<class T> class SegmentTree { public: // datのデータ構造 // 0123456789ABCDEF // インターフェースの添字 // ################ // 1--------------- // datの添字, 0は使わない!! // 2-------3------- // 4---5---6---7--- // 8-9-A-B-C-D-E-F- // GHIJKLMNOPQRSTUV // v<<1, v<<1|1は子どもたちを表している T *dat; AssosiativeOperator<T>* op; int n = 1; // 確保しているサイズ! int bits = 0; // n == 1 << bits const size_t size_; // 確保しているサイズではない!! int ql, qr; SegmentTree(int n_, AssosiativeOperator<T>* op) : size_(n_) { this->op = op; while(n < n_) { n <<= 1; bits++; } dat = pool.fetch<T>(n+n); fill_n(dat, n*4, this->op->T0); } // 点更新 void update(int v, const T &x){ v += n; dat[v] = x; while (v){ v = v >> 1; dat[v] = op->op(dat[v<<1|1], dat[v<<1]); } } // 範囲クエリ // 範囲番号nの区間[nl, nr)にop(x)を演算結果を返す T query(int n, int nl, int nr){ // この関数は、[ql, qr)より上のノードとその子の全てにHITする if(nr <= ql || qr <= nl) return op->T0; if(ql <= nl && nr <= qr) return dat[n]; // 一回の区間更新に付き最大3回、した区間が小さい順にHitする。 int m = (nl + nr) / 2; return op->op(query(n<<1|1, m, nr), query(n<<1, nl, m)); } // [l, r)の演算結果を出力 T query(int l, int r){ ql = l; qr = r; return query(1, 0, n); } }; int main(void) { ll n; cin >> n; SegmentTree<matrix> s(n, new AssosiativeOperatorMatrix<matrix>()); ll q; cin >> q; vll x(n), y(n); rep(i, q) { char query; cin >> query; if (query == 'a') { ll i; cin >> i; auto tmp = s.query(0, i); cout << tmp[0][0] + tmp[0][1] + tmp[0][2] + tmp[0][3] << endl; } else { ll i, v; cin >> i >> v; (query == 'x' ? x : y)[i] = v; matrix to_set = initial_mat(4); to_set[0][2] = x[i]; to_set[1][1] = y[i]; to_set[2][1] = 2*y[i]; to_set[2][2] = y[i]*y[i]; s.update(i, to_set); } } return 0; }