这个博客讲的很详细了。
但是有一个地方是错误的
https://blog.csdn.net/HelloWorld10086/article/details/48084941
这个地方要在乘 一个 b。
代码:
#include<bits/stdc++.h>
#define ls now << 1
#define rs now << 1 | 1
using namespace std;
const int N = 1e5+100;
const int mod = 10007;
int n,m,op;
long long lza[N*4],lzm[N*4],lzc[N*4];
long long sum[N*4][3];
long long ans[3];
void op3(int now,int len, int k){
lzc[now] = k; lza[now] = 0; lzm[now] = 1;
sum[now][0] = (1ll*len*k) % mod;
sum[now][1] = ((1ll*len*k) % mod *k) % mod;
sum[now][2] = (((1ll*len*k)%mod*k)%mod*k)%mod;
}
void op2(int now, int k){
lzm[now] = lzm[now]*k%mod; lza[now] = lza[now] * k % mod;
sum[now][0] = (sum[now][0]*k)%mod;
sum[now][1] = ((sum[now][1]*k)%mod*k)%mod;
sum[now][2] = (((sum[now][2]*k)%mod*k)%mod*k)%mod;
}
void op1(int now, int len, int k){
lza[now] += k;
sum[now][2] += ((1ll*3*sum[now][0]*k)%mod*k)%mod + (1ll*3*k*sum[now][1])%mod+(((1ll*len*k)%mod*k)%mod*k)%mod;
sum[now][1] += (1ll*2*sum[now][0]*k)%mod + ((1ll*len*k)%mod*k)%mod;
sum[now][0] += (1ll*len*k)%mod;
sum[now][0] %= mod; sum[now][1] %= mod; sum[now][2] %= mod;
}
void pushdown(int now, int l, int r){
int mid = (l + r) >> 1;
if (lzc[now]){
op3(ls,mid-l,lzc[now]); op3(rs,r-mid,lzc[now]);
lzc[now] = 0;
}
if (lzm[now] == 1 && lza[now] == 0) return;
op2(ls,lzm[now]); op2(rs,lzm[now]);
op1(ls,mid-l,lza[now]); op1(rs,r-mid,lza[now]);
lza[now] = 0; lzm[now] = 1;
}
void pushup(int now, int l, int r){
sum[now][0] = (sum[l][0] + sum[r][0])%mod;
sum[now][1] = (sum[l][1] + sum[r][1])%mod;
sum[now][2] = (sum[l][2] + sum[r][2])%mod;
}
void build(int now, int l, int r){
sum[now][0] = sum[now][1] = sum[now][2] = 0;
lza[now] = 0; lzm[now] = 1; lzc[now] = 0;
if (l + 1 == r) return;
int mid = (l + r) >> 1;
build(ls,l,mid); build(rs,mid,r);
}
void modify(int now, int l, int r, int a, int b, int k){
if (a <= l && b >= r-1){
int len = r - l;
if (op == 1){
op1(now,len,k);
} else if (op == 2) {
op2(now,k);
} else{
op3(now,len,k);
}
return;
}
pushdown(now,l,r);
int mid = (l + r) >> 1;
if (a < mid) modify(ls,l,mid,a,b,k);
if (b >= mid) modify(rs,mid,r,a,b,k);
pushup(now,ls,rs);
}
void query(int now, int l, int r, int a, int b){
if (a <= l && b >= r-1){
ans[0] += sum[now][0]; ans[1] += sum[now][1]; ans[2] += sum[now][2];
ans[0] %= mod; ans[1] %= mod; ans[2] %= mod;
return;
}
pushdown(now,l,r);
int mid = (l + r) >>1;
if (a < mid) query(ls,l,mid,a,b);
if (b >= mid) query(rs,mid,r,a,b);
}
int main(){
int x,y,z;
while(~scanf("%d%d",&n,&m)){
if (n == 0) break;
build(1,1,n+1);
for (int i = 0; i < m; ++i){
scanf("%d%d%d%d",&op,&x,&y,&z);
if (op == 4){
ans[0] = ans[2] = ans[1] = 0;
query(1,1,n+1,x,y);
printf("%lld\n",ans[z-1]);
}else{
modify(1,1,n+1,x,y,z);
}
}
}
return 0;
}