結果
| 問題 |
No.510 二次漸化式
|
| コンテスト | |
| ユーザー |
tottoripaper
|
| 提出日時 | 2017-05-05 22:01:37 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 528 ms / 3,000 ms |
| コード長 | 3,997 bytes |
| コンパイル時間 | 2,291 ms |
| コンパイル使用メモリ | 184,488 KB |
| 実行使用メモリ | 92,232 KB |
| 最終ジャッジ日時 | 2024-09-14 08:48:43 |
| 合計ジャッジ時間 | 18,373 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 34 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
#define fst(t) std::get<0>(t)
#define snd(t) std::get<1>(t)
#define thd(t) std::get<2>(t)
using ll = long long;
using P = std::tuple<int,int>;
const int dx[8] = {-1, 1, 0, 0, -1, -1, 1, 1}, dy[8] = {0, 0, -1, 1, -1, 1, -1, 1};
const ll MOD = 1e9 + 7;
template <typename T>
using Matrix = std::vector<std::vector<T>>;
namespace tottori{
template <typename T>
Matrix<T> mult(const Matrix<T>& m2, const Matrix<T>& m1){
assert(m1.size() > 0);
assert(m2.size() > 0);
assert(m1[0].size() == m2.size());
int n = m1.size(), m = m1[0].size(), l = m2[0].size();
Matrix<T> res(n);
for(int i=0;i<n;++i){
res[i].resize(l);
for(int j=0;j<l;++j){
for(int k=0;k<m;++k){
res[i][j] = (res[i][j] + m1[i][k] * m2[k][j]) % MOD;
}
}
}
return res;
}
};
// I want to delete this stupid solution ;(
#define sandwich(x) [](auto a, auto b){return (x)(a, b);}
template <typename T>
using F2 = std::function<T(T,T)>;
template <typename T, int N, typename F = std::plus<T>>
struct SegmentTree{
SegmentTree(T u, F f = F()){
size = 1;
while(size < N){
size <<= 1;
}
unit = u;
func = f;
init();
}
void init(){
for(int i=1;i<=2*size-1;++i){
data[i] = {{1, 0, 0, 0}, {0, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 0, 1}};
}
}
void update(int k, T v){
k += size;
data[k] = v;
while(k > 1){
k >>= 1;
data[k] = func(data[k*2], data[k*2+1]);
}
}
inline T query(int l, int r){
return _query(l, r, 1, 0, size);
}
T _query(int a, int b, int k, int l, int r){
if(b <= l || r <= a){return unit;}
if(a <= l && r <= b){return data[k];}
int mid = (l + r) >> 1;
return func(_query(a, b, 2*k, l, mid),
_query(a, b, 2*k+1, mid, r ));
}
T unit, data[N*4];
int size;
F func;
};
SegmentTree<Matrix<ll>, 100100, F2<Matrix<ll>>> segtree({{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}, sandwich(tottori::mult));
ll xs[100100], ys[100100];
void update(int i){
Matrix<ll> mat = {{1, 0, xs[i], 0}, {0, ys[i], 0, 1}, {0, ys[i] * 2 % MOD, ys[i] * ys[i] % MOD, 1}, {0, 0, 0, 1}};
segtree.update(i, mat);
}
int main(){
std::cin.tie(nullptr);
std::ios::sync_with_stdio(false);
int N;
std::cin >> N;
int Q;
std::cin >> Q;
for(int i=0;i<Q;++i){
char c;
std::cin >> c;
if(c == 'x'){
int i, v;
std::cin >> i >> v;
xs[i] = v;
update(i);
}else if(c == 'y'){
int i, v;
std::cin >> i >> v;
ys[i] = v;
update(i);
}else{
int i;
std::cin >> i;
int ai = 0;
if(i == 0){
ai = 1;
}else{
Matrix<ll> coefficientMatrix = segtree.query(0, i);
// auto f = [](const Matrix<ll>& mat){
// int n = mat.size(), m = mat[0].size();
// for(int i=0;i<n;++i){
// for(int j=0;j<m;++j){
// std::cout << mat[i][j] << " \n"[j+1==m];
// }
// }
// std::cout << "------------------------------------------------------------" << std::endl;
// };
for(int i=0;i<4;++i){
ai = (ai + coefficientMatrix[0][i]) % MOD;
}
}
std::cout << ai << std::endl;
}
}
}
tottoripaper