如题,2、9、10点RE 开了四倍数组,也写了防止死递归的代码(自认为不会死递归) 到现在还没搞明白为什么RE 求助各位神犇QwQ
ps:我的懒标记跟题解不大一样(我是自己琢磨的懒标记) 我的处理是当进行乘操作时就下放加懒标记,进行加操作时就下放乘懒标记
#include <iostream>
#include <cstdio>
#define LL long long
using namespace std;
struct Tree {
int lc;
int rc;
LL lzr;
LL lza;
LL sum;
Tree(
int lc = 0,
int rc = 0,
LL lzr = 1,
LL lza = 0,
LL sum = 0
) :
lc(lc),
rc(rc),
lzr(lzr),
lza(lza),
sum(sum)
{}
};
int n, m;
LL MOD;
Tree tree[100000 * 4 + 10];
int ca1, ca2, ca3;
LL ca4;
void build(int id, int l, int r)//建树
{
tree[id].lc = l;
tree[id].rc = r;
if (l == r) {
scanf("%lld", &tree[id].sum);
tree[id].sum %= MOD;
return ;
}
int mid = (l + r) >> 1;
build(id * 2, l, mid);
build(id * 2 + 1, mid + 1, r);
tree[id].sum = (tree[id * 2].sum + tree[id * 2 + 1].sum) % MOD;
}
void push_down_a(int id);
void push_down_r(int id);
void push_down_a(int id)//下放加懒标记
{
if (tree[id].lc != tree[id].rc && tree[id * 2].lzr != 1) push_down_r(id * 2);
if (tree[id].lc != tree[id].rc && tree[id * 2 + 1].lzr != 1) push_down_r(id * 2 + 1);
tree[id * 2].lza = (tree[id * 2].lza + tree[id].lza) % MOD;
tree[id * 2 + 1].lza = (tree[id * 2 + 1].lza + tree[id].lza) % MOD;
tree[id * 2].sum = (tree[id * 2].sum + tree[id].lza * (tree[id * 2].rc - tree[id * 2].lc + 1)) % MOD;
tree[id * 2 + 1].sum = (tree[id * 2 + 1].sum + tree[id].lza * (tree[id * 2 + 1].rc - tree[id * 2 + 1].lc + 1)) % MOD;
tree[id].lza = 0;
}
void push_down_r(int id)//下放乘懒标记
{
if (tree[id].lc != tree[id].rc && tree[id * 2].lza) push_down_a(id * 2);
if (tree[id].lc != tree[id].rc && tree[id * 2 + 1].lza) push_down_a(id * 2 + 1);
tree[id * 2].lzr = (tree[id * 2].lzr * tree[id].lzr) % MOD;
tree[id * 2 + 1].lzr = (tree[id * 2 + 1].lzr * tree[id].lzr) % MOD;
tree[id * 2].sum = (tree[id * 2].sum * tree[id].lzr) % MOD;
tree[id * 2 + 1].sum = (tree[id * 2 + 1].sum * tree[id].lzr) % MOD;
tree[id].lzr = 1;
}
void add(int id, int l, int r, LL k)//加法
{
if (l <= tree[id].lc && tree[id].rc <= r) {
if (tree[id].lc != tree[id].rc && tree[id].lzr != 1) push_down_r(id);
tree[id].lza = (tree[id].lza + k) % MOD;
tree[id].sum = (tree[id].sum + k * (tree[id].rc - tree[id].lc + 1)) % MOD;
return ;
}
if (tree[id].lza) push_down_a(id);
if (tree[id].lzr != 1) push_down_r(id);
if (l <= tree[id * 2].rc) add(id * 2, l, r, k);
if (r >= tree[id * 2 + 1].lc) add(id * 2 + 1, l, r, k);
tree[id].sum = (tree[id * 2].sum + tree[id * 2 + 1].sum) % MOD;
}
void ride(int id, int l, int r, LL k)//乘法
{
if (l <= tree[id].lc && tree[id].rc <= r) {
if (tree[id].lc != tree[id].rc && tree[id].lza) push_down_a(id);
tree[id].lzr = (tree[id].lzr * k) % MOD;
tree[id].sum = (tree[id].sum * k) % MOD;
return ;
}
if (tree[id].lza) push_down_a(id);
if (tree[id].lzr != 1) push_down_r(id);
if (l <= tree[id * 2].rc) ride(id * 2, l, r, k);
if (r >= tree[id * 2 + 1].lc) ride(id * 2 + 1, l, r, k);
tree[id].sum = (tree[id * 2].sum + tree[id * 2 + 1].sum) % MOD;
}
LL ask(int id, int l, int r)//求和
{
if (l <= tree[id].lc && tree[id].rc <= r) {
return tree[id].sum;
}
if (tree[id].lza) push_down_a(id);
if (tree[id].lzr != 1) push_down_r(id);
LL ans = 0;
if (l <= tree[id * 2].rc) ans = (ans + ask(id * 2, l, r)) % MOD;
if (r >= tree[id * 2 + 1].lc) ans = (ans + ask(id * 2 + 1, l, r)) % MOD;
return ans;
}
void test()//测试用函数
{
for(int i = 1; i <= n; ++i) printf("%lld ", ask(1, i, i));
}
int main()
{
scanf("%d%d%lld", &n, &m, &MOD);
build(1, 1, n);
//printf("test : ");test();printf("\n");
while (m--) {
scanf("%d", &ca1);
if (ca1 == 1) {
scanf("%d%d%lld", &ca2, &ca3, &ca4);
ride(1, ca2, ca3, ca4 % MOD);
// printf("test : ");test();printf("\n");
}
else if (ca1 == 2) {
scanf("%d%d%lld", &ca2, &ca3, &ca4);
add(1, ca2, ca3, ca4 % MOD);
// printf("test : ");test();printf("\n");
}
else {
scanf("%d%d", &ca2, &ca3);
printf("%lld\n", ask(1, ca2, ca3));
}
}
return 0;
}