洛谷__P2023 [AHOI2009] 维护序列(线段树)
题目链接:P2023 [AHOI2009] 维护序列 - 洛谷
题目大意:
有一个长为 的数列 ,有如下三种操作形式:
- 格式
1 t g c,表示把所有满足 的 改为 ; - 格式
2 t g c表示把所有满足 的 改为 ; - 格式
3 t g询问所有满足 的 的和,由于答案可能很大,你只需输出这个数模 的值。
代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<deque>
#include<stack>
#include<set>
#include<map>
#include<unordered_set>
#include<unordered_map>
#include<bitset>
#include<tuple>
#include<array>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/hash_policy.hpp>
#include <ext/numeric>
#define inf 72340172838076673
#define int long long
#define endl '\n'
#define F first
#define S second
#define mst(a,x) memset(a,x,sizeof (a))
#define gmap __gnu_pbds::gp_hash_table
#define power __gnu_cxx::power
using namespace std;
typedef pair<int, int> pii;
const int N = 200086;
int n, m, mod;
int w[N];
struct node {
int l, r;
int add, mul, sum;
} tr[N << 4];
void pushup(int u) {
tr[u].sum = (tr[u << 1].sum + tr[u << 1 | 1].sum) % mod;
}
void pushdown(int u) {
auto &root = tr[u], &lf = tr[u << 1], &ri = tr[u << 1 | 1];
if (root.mul != 1) {
lf.mul = (lf.mul * root.mul) % mod, ri.mul = (ri.mul * root.mul) % mod;
lf.add = (lf.add * root.mul) % mod, ri.add = (ri.add * root.mul) % mod;
lf.sum = (lf.sum * root.mul) % mod, ri.sum = (ri.sum * root.mul) % mod;
root.mul = 1;
}
if (root.add) {
lf.add = (lf.add + root.add) % mod, ri.add = (ri.add + root.add) % mod;
lf.sum = (lf.sum + (lf.r - lf.l + 1) * root.add) % mod;
ri.sum = (ri.sum + (ri.r - ri.l + 1) * root.add) % mod;
root.add = 0;
}
}
void build(int u, int l, int r) {
tr[u] = {l, r, 0, 1, w[l] % mod};
if (l == r) return;
int mid = l + r >> 1;
build(u << 1, l, mid);
build(u << 1 | 1, mid + 1, r);
pushup(u);
}
void modify1(int u, int l, int r, int x) {
if (l <= tr[u].l && tr[u].r <= r) {
tr[u].mul = (tr[u].mul * x) % mod;
tr[u].add = (tr[u].add * x) % mod;
tr[u].sum = (tr[u].sum * x) % mod;
return;
}
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1;
if (l <= mid) modify1(u << 1, l, r, x);
if (r > mid) modify1(u << 1 | 1, l, r, x);
pushup(u);
}
void modify2(int u, int l, int r, int x) {
if (l <= tr[u].l && tr[u].r <= r) {
tr[u].add = (tr[u].add + x) % mod;
tr[u].sum = (tr[u].sum + (tr[u].r - tr[u].l + 1) * x) % mod;
return;
}
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1;
if (l <= mid) modify2(u << 1, l, r, x);
if (r > mid) modify2(u << 1 | 1, l, r, x);
pushup(u);
}
int query(int u, int l, int r) {
if (l <= tr[u].l && tr[u].r <= r) return tr[u].sum % mod;
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1;
int res = 0;
if (l <= mid) res = query(u << 1, l, r) % mod;
if (r > mid) res = (res + query(u << 1 | 1, l, r)) % mod;
return res % mod;
}
void solve() {
cin >> n >> mod;
for (int i = 1; i <= n; i++) cin >> w[i];
build(1, 1, n);
cin >> m;
while (m--) {
int op, l, r, x;
cin >> op >> l >> r;
if (op == 1) {
cin >> x;
modify1(1, l, r, x);
} else if (op == 2) {
cin >> x;
modify2(1, l, r, x);
} else cout << query(1, l, r) % mod << endl;
}
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int T = 1;
// cin >> T;
while (T--) solve();
return 0;
}

浙公网安备 33010602011771号