记录编号 |
599113 |
评测结果 |
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
题目名称 |
[SYOI 2018] 简单的线段树 |
最终得分 |
100 |
用户昵称 |
LikableP |
是否通过 |
通过 |
代码语言 |
C++ |
运行时间 |
13.559 s |
提交时间 |
2025-02-28 19:09:15 |
内存使用 |
5.97 MiB |
显示代码纯文本
#pragma GCC optimize(2)
#include <iostream>
#include <cstdio>
#include <fstream>
#define ls(root) root << 1
#define rs(root) root << 1 | 1
#define Merge(root) tree[root] = (tree[ls(root)] + tree[rs(root)]) % p;
using namespace std;
typedef long long ll;
const int MAXN = 1e5;
int n, m, p;
ll a[MAXN + 10];
ll tree[(MAXN << 2) + 10], lazya[(MAXN << 2) + 10], lazym[(MAXN << 2) + 10];
void Build(int root, int lt, int rt) {
lazym[root] = 1;
if (lt == rt) return ;
int mid = lt + ((rt - lt) >> 1);
Build(ls(root), lt, mid);
Build(rs(root), mid + 1, rt);
return ;
}
void PushDown(int root, int lt, int rt) {
if (lazya[root] == 0 && lazym[root] == 1) return ;
(tree[ls(root)] *= lazym[root]) %= p;
(lazym[ls(root)] *= lazym[root]) %= p;
(lazya[ls(root)] *= lazym[root]) %= p;
(tree[rs(root)] *= lazym[root]) %= p;
(lazym[rs(root)] *= lazym[root]) %= p;
(lazya[rs(root)] *= lazym[root]) %= p;
lazym[root] = 1;
int mid = lt + ((rt - lt) >> 1);
(tree[ls(root)] += (mid - lt + 1) * 1ll * lazya[root]) %= p;
(lazya[ls(root)] += lazya[root]) %= p;
(tree[rs(root)] += (rt - mid) * 1ll * lazya[root]) %= p;
(lazya[rs(root)] += lazya[root]) %= p;
lazya[root] = 0;
return ;
}
ll GetSeq(int root, int lt, int rt, int lq, int rq) {
if (lt == lq && rt == rq) {
return tree[root];
}
PushDown(root, lt, rt);
int mid = lt + ((rt - lt) >> 1);
if (rq <= mid) {
return GetSeq(ls(root), lt, mid, lq, rq);
} else if (lq > mid) {
return GetSeq(rs(root), mid + 1, rt, lq, rq);
} else {
return GetSeq(ls(root), lt, mid, lq, mid) + GetSeq(rs(root), mid + 1, rt, mid + 1, rq);
}
}
void AddSeq(int root, int lt, int rt, int lq, int rq, int val) {
if (lt == lq && rt == rq) {
(tree[root] += (rt - lt + 1) * 1ll * val) %= p;
(lazya[root] += val) %= p;
return ;
}
PushDown(root, lt, rt);
int mid = lt + ((rt - lt) >> 1);
if (rq <= mid) {
AddSeq(ls(root), lt, mid, lq, rq, val);
} else if (lq > mid) {
AddSeq(rs(root), mid + 1, rt, lq, rq, val);
} else {
AddSeq(ls(root), lt, mid, lq, mid, val);
AddSeq(rs(root), mid + 1, rt, mid + 1, rq, val);
}
Merge(root);
return ;
}
void MulSeq(int root, int lt, int rt, int lq, int rq, int val) {
if (lt == lq && rt == rq) {
(tree[root] *= val) %= p;
(lazya[root] *= val) %= p;
(lazym[root] *= val) %= p;
return ;
}
PushDown(root, lt, rt);
int mid = lt + ((rt - lt) >> 1);
if (rq <= mid) {
MulSeq(ls(root), lt, mid, lq, rq, val);
} else if (lq > mid) {
MulSeq(rs(root), mid + 1, rt, lq, rq, val);
} else {
MulSeq(ls(root), lt, mid, lq, mid, val);
MulSeq(rs(root), mid + 1, rt, mid + 1, rq, val);
}
Merge(root);
return ;
}
int main() {
freopen("easilysegmenttree.in", "r", stdin);
freopen("easilysegmenttree.out", "w", stdout);
scanf("%d %d %d", &n, &m, &p);
Build(1, 1, n);
while (m--) {
int op, l, r, v;
scanf("%d %d %d", &op, &l, &r);
if (op == 1) {
scanf("%d", &v);
AddSeq(1, 1, n, l, r, v);
} else if (op == 2) {
scanf("%d", &v);
MulSeq(1, 1, n, l, r, v);
} else if (op == 3) {
printf("%lld\n", GetSeq(1, 1, n, l, r) % p);
} else {
printf("QwQ");
}
}
return 0;
}