結果
| 問題 |
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;
}