1.​​题目链接​​。题意其实还是比较简单的,大概就是一些线段树区间修改的操作集合起来吧。

2.每个节点维护八个信息:区间[l,r].然后是三个区间和,区间元素和,区间元素平方和,区间元素立方和。然后是三个lazy标记,lazy1:区间元素的增量,lazy2:区间元素乘的数值,lazy3:区间元素改变的数值.然后就是区间修改区间查询的操作了。代码写起来很复杂,理解难度很小。

#include<bits/stdc++.h>
using namespace std;
const int MOD = 10007;
const int MAXN = 100010;
#pragma warning(disable:4996)
struct Node
{
int l, r;
int sum1, sum2, sum3;
int lazy1, lazy2, lazy3;
}segTree[MAXN * 3];
void build(int i, int l, int r)
{
segTree[i].l = l;
segTree[i].r = r;
segTree[i].sum1 = segTree[i].sum2 = segTree[i].sum3 = 0;
segTree[i].lazy1 = segTree[i].lazy3 = 0;
segTree[i].lazy2 = 1;
int mid = (l + r) / 2;
if (l == r)return;
build(i << 1, l, mid);
build((i << 1) | 1, mid + 1, r);
}
void push_up(int i)
{
if (segTree[i].l == segTree[i].r)
return;
segTree[i].sum1 = (segTree[i << 1].sum1 + segTree[(i << 1) | 1].sum1) % MOD;
segTree[i].sum2 = (segTree[i << 1].sum2 + segTree[(i << 1) | 1].sum2) % MOD;
segTree[i].sum3 = (segTree[i << 1].sum3 + segTree[(i << 1) | 1].sum3) % MOD;

}

void push_down(int i)
{
if (segTree[i].l == segTree[i].r) return;
if (segTree[i].lazy3 != 0)
{
segTree[i << 1].lazy3 = segTree[(i << 1) | 1].lazy3 = segTree[i].lazy3;
segTree[i << 1].lazy1 = segTree[(i << 1) | 1].lazy1 = 0;
segTree[i << 1].lazy2 = segTree[(i << 1) | 1].lazy2 = 1;
segTree[i << 1].sum1 = (segTree[i << 1].r - segTree[i << 1].l + 1)*segTree[i << 1].lazy3%MOD;
segTree[i << 1].sum2 = (segTree[i << 1].r - segTree[i << 1].l + 1)*segTree[i << 1].lazy3%MOD*segTree[i << 1].lazy3%MOD;
segTree[i << 1].sum3 = (segTree[i << 1].r - segTree[i << 1].l + 1)*segTree[i << 1].lazy3%MOD*segTree[i << 1].lazy3%MOD*segTree[i << 1].lazy3%MOD;
segTree[(i << 1) | 1].sum1 = (segTree[(i << 1) | 1].r - segTree[(i << 1) | 1].l + 1)*segTree[(i << 1) | 1].lazy3%MOD;
segTree[(i << 1) | 1].sum2 = (segTree[(i << 1) | 1].r - segTree[(i << 1) | 1].l + 1)*segTree[(i << 1) | 1].lazy3%MOD*segTree[(i << 1) | 1].lazy3%MOD;
segTree[(i << 1) | 1].sum3 = (segTree[(i << 1) | 1].r - segTree[(i << 1) | 1].l + 1)*segTree[(i << 1) | 1].lazy3%MOD*segTree[(i << 1) | 1].lazy3%MOD*segTree[(i << 1) | 1].lazy3%MOD;
segTree[i].lazy3 = 0;
}
if (segTree[i].lazy1 != 0 || segTree[i].lazy2 != 1)
{
segTree[i << 1].lazy1 = (segTree[i].lazy2*segTree[i << 1].lazy1%MOD + segTree[i].lazy1) % MOD;
segTree[i << 1].lazy2 = segTree[i << 1].lazy2*segTree[i].lazy2%MOD;
int sum1, sum2, sum3;
sum1 = (segTree[i << 1].sum1*segTree[i].lazy2%MOD + (segTree[i << 1].r - segTree[i << 1].l + 1)*segTree[i].lazy1%MOD) % MOD;
sum2 = (segTree[i].lazy2 * segTree[i].lazy2 % MOD * segTree[i << 1].sum2 % MOD + 2 * segTree[i].lazy1*segTree[i].lazy2%MOD * segTree[i << 1].sum1%MOD + (segTree[i << 1].r - segTree[i << 1].l + 1)*segTree[i].lazy1%MOD*segTree[i].lazy1%MOD) % MOD;
sum3 = segTree[i].lazy2 * segTree[i].lazy2 % MOD * segTree[i].lazy2 % MOD * segTree[i << 1].sum3 % MOD;
sum3 = (sum3 + 3 * segTree[i].lazy2 % MOD * segTree[i].lazy2 % MOD * segTree[i].lazy1 % MOD * segTree[i << 1].sum2) % MOD;
sum3 = (sum3 + 3 * segTree[i].lazy2 % MOD * segTree[i].lazy1 % MOD * segTree[i].lazy1 % MOD * segTree[i << 1].sum1) % MOD;
sum3 = (sum3 + (segTree[i << 1].r - segTree[i << 1].l + 1)*segTree[i].lazy1%MOD * segTree[i].lazy1 % MOD * segTree[i].lazy1 % MOD) % MOD;
segTree[i << 1].sum1 = sum1;
segTree[i << 1].sum2 = sum2;
segTree[i << 1].sum3 = sum3;
segTree[(i << 1) | 1].lazy1 = (segTree[i].lazy2*segTree[(i << 1) | 1].lazy1%MOD + segTree[i].lazy1) % MOD;
segTree[(i << 1) | 1].lazy2 = segTree[(i << 1) | 1].lazy2 * segTree[i].lazy2 % MOD;
sum1 = (segTree[(i << 1) | 1].sum1*segTree[i].lazy2%MOD + (segTree[(i << 1) | 1].r - segTree[(i << 1) | 1].l + 1)*segTree[i].lazy1%MOD) % MOD;
sum2 = (segTree[i].lazy2 * segTree[i].lazy2 % MOD * segTree[(i << 1) | 1].sum2 % MOD + 2 * segTree[i].lazy1*segTree[i].lazy2%MOD * segTree[(i << 1) | 1].sum1%MOD + (segTree[(i << 1) | 1].r - segTree[(i << 1) | 1].l + 1)*segTree[i].lazy1%MOD*segTree[i].lazy1%MOD) % MOD;
sum3 = segTree[i].lazy2 * segTree[i].lazy2 % MOD * segTree[i].lazy2 % MOD * segTree[(i << 1) | 1].sum3 % MOD;
sum3 = (sum3 + 3 * segTree[i].lazy2 % MOD * segTree[i].lazy2 % MOD * segTree[i].lazy1 % MOD * segTree[(i << 1) | 1].sum2) % MOD;
sum3 = (sum3 + 3 * segTree[i].lazy2 % MOD * segTree[i].lazy1 % MOD * segTree[i].lazy1 % MOD * segTree[(i << 1) | 1].sum1) % MOD;
sum3 = (sum3 + (segTree[(i << 1) | 1].r - segTree[(i << 1) | 1].l + 1)*segTree[i].lazy1%MOD * segTree[i].lazy1 % MOD * segTree[i].lazy1 % MOD) % MOD;
segTree[(i << 1) | 1].sum1 = sum1;
segTree[(i << 1) | 1].sum2 = sum2;
segTree[(i << 1) | 1].sum3 = sum3;
segTree[i].lazy1 = 0;
segTree[i].lazy2 = 1;

}
}
void update(int i, int l, int r, int type, int c)
{
if (segTree[i].l == l && segTree[i].r == r)
{
c %= MOD;
if (type == 1)
{
segTree[i].lazy1 += c;
segTree[i].lazy1 %= MOD;
segTree[i].sum3 = (segTree[i].sum3 + 3 * segTree[i].sum2%MOD*c%MOD + 3 * segTree[i].sum1%MOD*c%MOD*c%MOD + (segTree[i].r - segTree[i].l + 1)*c%MOD*c%MOD*c%MOD) % MOD;
segTree[i].sum2 = (segTree[i].sum2 + 2 * segTree[i].sum1%MOD*c%MOD + (segTree[i].r - segTree[i].l + 1)*c%MOD*c%MOD) % MOD;
segTree[i].sum1 = (segTree[i].sum1 + (segTree[i].r - segTree[i].l + 1)*c%MOD) % MOD;
}
else if (type == 2)
{
segTree[i].lazy1 = segTree[i].lazy1*c%MOD;
segTree[i].lazy2 = segTree[i].lazy2*c%MOD;
segTree[i].sum1 = segTree[i].sum1*c%MOD;
segTree[i].sum2 = segTree[i].sum2*c%MOD*c%MOD;
segTree[i].sum3 = segTree[i].sum3*c%MOD*c%MOD*c%MOD;
}
else
{
segTree[i].lazy1 = 0;
segTree[i].lazy2 = 1;
segTree[i].lazy3 = c % MOD;
segTree[i].sum1 = c * (segTree[i].r - segTree[i].l + 1) % MOD;
segTree[i].sum2 = c * (segTree[i].r - segTree[i].l + 1) % MOD*c%MOD;
segTree[i].sum3 = c * (segTree[i].r - segTree[i].l + 1) % MOD*c%MOD*c%MOD;
}
return;
}
push_down(i);
int mid = (segTree[i].l + segTree[i].r) / 2;
if (r <= mid)update(i << 1, l, r, type, c);
else if (l > mid)update((i << 1) | 1, l, r, type, c);
else
{
update(i << 1, l, mid, type, c);
update((i << 1) | 1, mid + 1, r, type, c);
}
push_up(i);
}
int query(int i, int l, int r, int p)
{
if (segTree[i].l == l && segTree[i].r == r)
{
if (p == 1)return segTree[i].sum1;
else if (p == 2)return segTree[i].sum2;
else return segTree[i].sum3;
}
push_down(i);
int mid = (segTree[i].l + segTree[i].r) / 2;
if (r <= mid)return query(i << 1, l, r, p);
else if (l > mid)return query((i << 1) | 1, l, r, p);
else return (query(i << 1, l, mid, p) + query((i << 1) | 1, mid + 1, r, p)) % MOD;
}

int main()
{
int n, m;
while (scanf("%d%d", &n, &m) == 2)
{
if (n == 0 && m == 0)break;
build(1, 1, n);
int type, x, y, c;
while (m--)
{
scanf("%d%d%d%d", &type, &x, &y, &c);
if (type == 4)printf("%d\n", query(1, x, y, c));
else update(1, x, y, type, c);
}
}
return 0;
}