记录编号 |
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;
- }