- TopAI
DeepSeek
- @ 2025-8-26 21:08:35
如题,已知一个数列 a,你需要进行下面三种操作:
将某区间每一个数乘上 x;
将某区间每一个数加上 x;
求出某区间每一个数的和。
输入格式
第一行包含三个整数 n,q,m,分别表示该数列数字的个数、操作的总个数和模数。
第二行包含 n 个用空格分隔的整数,其中第 i 个数字表示数列第 i 项的初始值 ai。
接下来 q 行每行包含若干个整数,表示一个操作,具体如下:
操作 1: 格式:1 x y k 含义:将区间 [x,y] 内每个数乘上 k。
操作 2: 格式:2 x y k 含义:将区间 [x,y] 内每个数加上 k。
操作 3: 格式:3 x y 含义:输出区间 [x,y] 内每个数的和对 m 取模所得的结果。 【数据范围】
对于 30% 的数据:n≤8,q≤10。 对于 70% 的数据:n≤103,q≤104。 对于 100% 的数据:1≤n≤105,1≤q≤105,1≤ai,k≤104。
// 维护序列
// P3373
#include <iostream>
#define lc u << 1
#define rc u << 1 | 1
#define LL long long
using namespace std;
const int N = 1e5 + 1023;
int n, q, m, w[N];
struct Tree {
int l, r;
LL sum;
LL add, mul;
}tr[N << 2];
inline void pushup(int u) { tr[u].sum = (tr[lc].sum + tr[rc].sum) % q; }
inline void calc(Tree &t, LL m, LL a) {
t.sum = (t.sum * m + t.add * (t.r - t.l + 1)) % q;
t.mul = t.mul * m % q;
t.add = (t.add * m + a) % q;
}
inline void pushdown(int u) {
calc(tr[lc], tr[u].mul, tr[u].add);
calc(tr[rc], tr[u].mul, tr[u].add);
tr[u].add = 0;
tr[u].mul = 1;
}
void build(int u, int l, int r) {
tr[u] = {l, r, 0, 0, 1};
if (l == r) {
tr[u].sum = w[l] % q;
return;
}
int mid = l + r >> 1;
build(lc, l, mid);
build(rc, mid + 1, r);
pushup(u);
}
void change(int u, int l, int r, LL m, LL a) {
//cout << tr[u].l << ' ' << tr[u].r << '\n' ;
if (l <= tr[u].l && tr[u].r <= r) {
calc(tr[u], m, a);
return;
}
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1;
if (l <= mid) change(lc, l, r, m, a);
if (r > mid) change(rc, l, r, m, a);
pushup(u);
}
LL query(int u, int l, int r) {
if (l <= tr[u].l && tr[u].r <= r) return tr[u].sum;
pushdown(u);
LL ans = 0, mid = tr[u].l + tr[u].r >> 1;
if (l <= mid) (ans += query(lc, l, r)) %= q;
if (r > mid) (ans += query(rc, l, r)) %= q;
return ans;
}
int main()
{
cin >> n >> m;
cin >> q;
for (int i = 1; i <= n; i++) cin >> w[i];
build(1, 1, n);
//cin >> m;
for (int k, l, r; m--;) {
LL v;
cin >> k >> l >> r;
if (k < 3) {
cin >> v;
change(1, l, r, k == 1 ? v : 1, k == 2 ? v : 0);
} else {
cout << query(1, l, r) << '\n';
}
}
return 0;
}
修改
0 条评论
目前还没有评论...