QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#445326 | #6435. Paimon Segment Tree | lym | RE | 0ms | 0kb | C++20 | 4.9kb | 2024-06-16 01:16:54 | 2024-06-16 01:16:54 |
answer
#include<bits/stdc++.h>
#pragma gcc optimize("O2")
#pragma g++ optimize("O2")
using i64 = long long;
const int mod = 1e9 + 7;
struct Matrix {
int n = 4;
std::vector<std::vector<int> > M;
Matrix() {}
void init(int n = 4) {
this -> n = n;
M.assign(n + 1, std::vector<int>(n + 1, 0));
}
void norm() {
init();
for (int i = 1; i <= n; i ++) {
M[i][i] = 1;
}
}
void Form(int v) {
init();
M[1][2] = v;
M[1][3] = M[1][4] = 1ll * v * v % mod;
M[2][3] = M[2][4] = 2 * v % mod;
M[3][4] = 1;
M[1][1] = M[2][2] = M[3][3] = M[4][4] = 1;
}
Matrix friend operator * (const Matrix &a, const Matrix &b) {
Matrix ans;
int n = a.n;
ans.init(n);
for (int i = 1; i <= n; i ++) {
for (int j = 1; j <= n; j ++) {
for (int k = 1; k <= n; k ++) {
ans.M[i][j] = (1ll * ans.M[i][j] + 1ll * a.M[i][k] * b.M[k][j] % mod) % mod;
}
}
}
return ans;
}
Matrix friend operator + (const Matrix &a, const Matrix &b) {
Matrix ans;
int n = a.n;
ans.init(n);
for (int i = 1; i <= n; i ++) {
for (int j = 1; j <= n; j ++) {
ans.M[i][j] = (a.M[i][j] + b.M[i][j]) % mod;
}
}
return ans;
}
};
const int N = 1e5 + 10;
int a[N];
Matrix add[N * 4];
Matrix val[N * 4];
struct SegmentTree {
int n;
std::vector<int> a;
SegmentTree() {}
void init(int n) {
this -> n = n;
build(1, 1, n);
}
void pushup(int u) {
val[u] = val[u << 1] + val[u << 1 | 1];
}
void pushdown(int u) {
val[u << 1] = val[u << 1] * add[u];
val[u << 1 | 1] = val[u << 1 | 1] * add[u];
add[u << 1] = add[u << 1] * add[u];
add[u << 1 | 1] = add[u << 1 | 1] * add[u];
add[u].norm();
}
void build(int u, int l, int r) {
val[u].init();
add[u].norm();
if (l == r) {
val[u].M[1][1] = 1;
val[u].M[1][2] = a[l];
val[u].M[1][3] = 1ll * a[l] * a[l] % mod;
val[u].M[1][4] = 1ll * a[l] * a[l] % mod;
return ;
}
int mid = l + r >> 1;
build(u << 1, l, mid);
build(u << 1 | 1, mid + 1, r);
pushup(u);
}
void addd(int u, int L, int R, int l, int r, int v) {
if (L >= l && R <= r) {
Matrix tmp;
tmp.Form(v);
val[u] = val[u] * tmp;
add[u] = add[u] * tmp;
return ;
}
pushdown(u);
int mid = L + R >> 1;
if (l <= mid) addd(u << 1, L, mid, l, r, v);
if (r > mid) addd(u << 1 | 1, mid + 1, R, l, r, v);
pushup(u);
}
int query(int u, int L, int R, int l, int r) {
if (L >= l && R <= r) {
return val[u].M[1][4];
}
pushdown(u);
int res = 0;
int mid = L + R >> 1;
if (l <= mid) res = (res + query(u << 1, L, mid, l, r)) % mod;
if (mid < r) res = (res + query(u << 1 | 1, mid + 1, R, l, r)) % mod;
return res;
}
void addd(int l, int r, int v) {
addd(1, 1, n, l, r, v);
}
int query(int l, int r) {
return query(1, 1, n, l, r); // D, history sum.
}
};
namespace ffastIO {
const int bufl = 1 << 15;
char buf[bufl], *s = buf, *t = buf;
inline int fetch() {
if (s == t) { t = (s = buf) + fread(buf, 1, bufl, stdin); if (s == t) return EOF; }
return *s++;
}
inline int read() {
int a = 0, b = 1, c = fetch();
while (!isdigit(c))b ^= c == '-', c = fetch();
while (isdigit(c)) a = a * 10 + c - 48, c = fetch();
return b ? a : -a;
}
}
using ffastIO::read;
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int n = read(), m = read(), q = read();
for (int i = 1; i <= n; i ++) {
a[i] = (read() + mod) % mod;
}
SegmentTree t;
t.init(n);
std::vector<std::array<int, 3> > op(m + 1);
for (int i = 1; i <= m; i ++) {
std::cin >> op[i][0] >> op[i][1] >> op[i][2];
op[i][0] = read();
op[i][1] = read();
op[i][2] = (read() + mod) % mod;
}
std::vector<std::vector<std::array<int, 4> > > p(m + 1);
std::vector<int> ans(q + 1);
for (int i = 1; i <= q; i ++) {
int l = read(), r = read(), x = read(), y = read();
if (x - 1 >= 0) p[x - 1].push_back({-1, i, l, r});
p[y].push_back({1, i, l, r});
}
for (int i = 0; i <= m; i ++) {
if (i) {
int l = op[i][0], r = op[i][1], v = op[i][2];
t.addd(l, r, v);
if (l - 1 >= 1) t.addd(1, l - 1, 0);
if (r + 1 <= n) t.addd(r + 1, n, 0);
}
for (auto it : p[i]) {
int sig = it[0], j = it[1], l = it[2], r = it[3];
int val = t.query(l, r);
//std::cout << ans[j] << ' ' << val << ' ' << l << ' ' << r << ' ' << "???\n";
ans[j] = (ans[j] + val * sig) % mod;
}
//std::cout << "TEST : " << t.query(4, 4) << '\n';
}
for (int i = 1; i <= q; i ++) {
ans[i] = (ans[i] + mod) % mod;
std::cout << ans[i] << '\n';
}
return 0;
}
/*
4 1 1
2 3 2 2
1 1 6
4 4 0 1
*/
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 0
Runtime Error
input:
3 1 1 8 1 6 2 3 2 2 2 0 0