結果
問題 |
No.510 二次漸化式
|
ユーザー |
|
提出日時 | 2025-02-24 17:20:15 |
言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 150 ms / 3,000 ms |
コード長 | 3,025 bytes |
コンパイル時間 | 2,249 ms |
コンパイル使用メモリ | 180,148 KB |
実行使用メモリ | 35,544 KB |
最終ジャッジ日時 | 2025-02-24 17:20:27 |
合計ジャッジ時間 | 6,934 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 34 |
ソースコード
#include<bits/stdc++.h> #define ls(k) k << 1 #define rs(k) k << 1 | 1 #define fi first #define se second #define open(s1, s2) freopen(s1, "r", stdin), freopen(s2, "w", stdout); using namespace std; typedef __int128 __; typedef long double lb; typedef double db; typedef unsigned long long ull; typedef long long ll; bool Begin; const int N = 1e5 + 10, M = 4, mod = 1e9 + 7; inline ll read(){ ll x = 0, f = 1; char c = getchar(); while(c < '0' || c > '9'){ if(c == '-') f = -1; c = getchar(); } while(c >= '0' && c <= '9'){ x = (x << 1) + (x << 3) + (c ^ 48); c = getchar(); } return x * f; } inline void write(ll x){ if(x < 0){ putchar('-'); x = -x; } if(x > 9) write(x / 10); putchar(x % 10 + '0'); } char op; int n, q, a, v; int x[N], y[N]; struct Mat{ int n, m; int a[M][M]; Mat(){ n = m = 0; memset(a, 0, sizeof(a)); } Mat(int _n, int _m){ n = _n, m = _m; for(int i = 0; i < n; ++i) a[i][i] = 1; } inline void init(int _n, int _m){ n = _n, m = _m; memset(a, 0, sizeof(a)); } inline int* operator[](int i){ return a[i]; } inline friend Mat operator*(Mat A, Mat B){ Mat ans; ans.n = A.n, ans.m = B.m; for(int i = 0; i < A.n; ++i) for(int j = 0; j < B.m; ++j) for(int k = 0; k < A.m; ++k) ans[i][j] = (ans[i][j] + 1ll * A[i][k] * B[k][j] % mod) % mod; return ans; } }now; struct Node{ int l, r; Mat mul; }X[N << 2]; inline void pushup(int k){ X[k].mul = X[k << 1 | 1].mul * X[k << 1].mul; } inline void newmat(Mat &a, int x, int y){ a.init(4, 4); a[0][0] = a[1][3] = a[2][3] = a[3][3] = 1; a[0][2] = x, a[1][1] = y, a[2][1] = 2ll * y % mod, a[2][2] = 1ll * y * y % mod; } inline void build(int k, int l, int r){ X[k].l = l, X[k].r = r; if(l == r){ newmat(X[k].mul, 0, 0); return ; } int mid = (l + r) >> 1; build(k << 1, l, mid); build(k << 1 | 1, mid + 1, r); pushup(k); } inline void update(int k, int i){ if(X[k].l == i && i == X[k].r){ newmat(X[k].mul, x[i], y[i]); return ; } int mid = (X[k].l + X[k].r) >> 1; if(i <= mid) update(k << 1, i); else update(k << 1 | 1, i); pushup(k); } inline Mat query(int k, int l, int r){ if(X[k].l == l && r == X[k].r) return X[k].mul; int mid = (X[k].l + X[k].r) >> 1; if(r <= mid) return query(k << 1, l, r); else if(l > mid) return query(k << 1 | 1, l, r); else return query(k << 1 | 1, mid + 1, r) * query(k << 1, l, mid); } bool End; int main(){ // open("A.in", "A.out"); now.init(4, 1); now[0][0] = now[1][0] = now[2][0] = now[3][0] = 1; n = read(), q = read(); build(1, 0, n); while(q--){ cin >> op; if(op == 'x'){ a = read(), v = read(); x[a] = v; update(1, a); } else if(op == 'y'){ a = read(), v = read(); y[a] = v; update(1, a); } else{ a = read(); if(!a){ puts("1"); continue; } Mat ans = query(1, 0, a - 1) * now; write(ans[0][0]); putchar('\n'); } } cerr << '\n' << abs(&Begin - &End) / 1048576 << "MB"; return 0; }