简单的线段树,三种操作所以使用三种lazy标记,三种幂都可以进行转化,乘法和全部变成一种数比较好做,加法则把每一项拆开就行了,贴上代码。。
#include <iostream>
#include <sstream>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <climits>
#define maxn 100005
#define eps 1e-6
#define mod 10007
#define INF 99999999
#define lowbit(x) (x&(-x))
#define lson o<<1, L, mid
#define rson o<<1 | 1, mid+1, R
typedef long long LL;
using namespace std;
int sum[4][maxn<<2];
int mark[4][maxn<<2];
int ans, v;
int ql, qr, k;
int n, m;
void init(void)
{
memset(sum, 0, sizeof sum);
memset(mark, 0, sizeof mark);
}
void pushdown(int o, int L, int R)
{
int mid=(R+L)>>1;
if(mark[3][o]){
sum[1][o<<1]=(mid-L+1)*mark[3][o]%mod;
sum[1][o<<1 | 1]=(R-mid)*mark[3][o]%mod;
sum[2][o<<1]=(mid-L+1)*mark[3][o]%mod*mark[3][o]%mod;
sum[2][o<<1 | 1]=(R-mid)*mark[3][o]%mod*mark[3][o]%mod;
sum[3][o<<1]=(mid-L+1)*mark[3][o]%mod*mark[3][o]%mod*mark[3][o]%mod;
sum[3][o<<1 | 1]=(R-mid)*mark[3][o]%mod*mark[3][o]%mod*mark[3][o]%mod;
mark[3][o<<1]=mark[3][o<<1 | 1]=mark[3][o];
mark[1][o<<1]=mark[1][o<<1 | 1]=mark[2][o<<1]=mark[2][o<<1 | 1]=mark[3][o]=0;
}
if(mark[2][o]){
sum[1][o<<1]=sum[1][o<<1]*mark[2][o]%mod;
sum[1][o<<1 | 1]=sum[1][o<<1 | 1]*mark[2][o]%mod;
sum[2][o<<1]=sum[2][o<<1]*mark[2][o]%mod*mark[2][o]%mod;
sum[2][o<<1 | 1]=sum[2][o<<1 | 1]*mark[2][o]%mod*mark[2][o]%mod;
sum[3][o<<1]=sum[3][o<<1]*mark[2][o]%mod*mark[2][o]%mod*mark[2][o]%mod;
sum[3][o<<1 | 1]=sum[3][o<<1 | 1]*mark[2][o]%mod*mark[2][o]%mod*mark[2][o]%mod;
mark[1][o<<1]=mark[1][o<<1]*mark[2][o]%mod;
mark[1][o<<1 | 1]=mark[1][o<<1 | 1]*mark[2][o]%mod;
if(mark[2][o<<1]) mark[2][o<<1]=mark[2][o<<1]*mark[2][o]%mod;
else mark[2][o<<1]=mark[2][o];
if(mark[2][o<<1 | 1]) mark[2][o<<1 | 1]=mark[2][o<<1 | 1]*mark[2][o]%mod;
else mark[2][o<<1 | 1]=mark[2][o];
mark[2][o]=0;
}
if(mark[1][o]){
sum[3][o<<1]=(sum[3][o<<1]+3*sum[2][o<<1]*mark[1][o]%mod+3*sum[1][o<<1]*mark[1][o]%mod*mark[1][o]%mod+mark[1][o]*mark[1][o]%mod*mark[1][o]%mod*(mid-L+1)%mod)%mod;
sum[3][o<<1 | 1]=(sum[3][o<<1 | 1]+3*sum[2][o<<1 | 1]*mark[1][o]%mod+3*sum[1][o<<1 | 1]*mark[1][o]%mod*mark[1][o]%mod+mark[1][o]*mark[1][o]%mod*mark[1][o]%mod*(R-mid)%mod)%mod;
sum[2][o<<1]=(sum[2][o<<1]+2*mark[1][o]*sum[1][o<<1]%mod+mark[1][o]*mark[1][o]%mod*(mid-L+1)%mod)%mod;
sum[2][o<<1 | 1]=(sum[2][o<<1 | 1]+2*mark[1][o]*sum[1][o<<1 | 1]%mod+mark[1][o]*mark[1][o]%mod*(R-mid)%mod)%mod;
sum[1][o<<1]=(sum[1][o<<1]+(mid-L+1)*mark[1][o]%mod)%mod;
sum[1][o<<1 | 1]=(sum[1][o<<1 | 1]+(R-mid)*mark[1][o]%mod)%mod;
mark[1][o<<1]=(mark[1][o<<1]+mark[1][o])%mod;
mark[1][o<<1 | 1]=(mark[1][o<<1 | 1]+mark[1][o])%mod;
mark[1][o]=0;
}
}
void pushup(int o)
{
for(int i=1;i<=3;i++)
sum[i][o]=(sum[i][o<<1]+sum[i][o<<1 | 1])%mod;
}
void query(int o, int L, int R)
{
if(ql<=L && qr>=R){
ans=(ans+sum[k][o])%mod;
return;
}
pushdown(o, L, R);
int mid=(R+L)>>1;
if(ql<=mid) query(lson);
if(qr>mid) query(rson);
pushup(o);
}
void updata(int o, int L, int R)
{
if(ql<=L && qr>=R){
if(k==3){
sum[1][o]=(R-L+1)*v%mod;
sum[2][o]=(R-L+1)*v%mod*v%mod;
sum[3][o]=(R-L+1)*v%mod*v%mod*v%mod;
mark[1][o]=mark[2][o]=0;
mark[3][o]=v;
}
if(k==2){
sum[1][o]=sum[1][o]*v%mod;
sum[2][o]=sum[2][o]*v%mod*v%mod;
sum[3][o]=sum[3][o]*v%mod*v%mod*v%mod;
mark[1][o]=mark[1][o]*v%mod;
if(mark[2][o]) mark[2][o]=mark[2][o]*v%mod;
else mark[2][o]=v;
}
if(k==1){
sum[3][o]=(sum[3][o]+3*sum[2][o]%mod*v%mod+3*sum[1][o]*v%mod*v%mod+v*v%mod*v%mod*(R-L+1)%mod)%mod;
sum[2][o]=(sum[2][o]+2*sum[1][o]*v%mod+v*v%mod*(R-L+1)%mod)%mod;
sum[1][o]=(sum[1][o]+v*(R-L+1)%mod)%mod;
mark[1][o]=(mark[1][o]+v)%mod;
}
return;
}
pushdown(o, L, R);
int mid=(R+L)>>1;
if(ql<=mid) updata(lson);
if(qr>mid) updata(rson);
pushup(o);
}
void solve(void)
{
while(m--){
scanf("%d",&k);
if(k==4){
scanf("%d%d%d",&ql,&qr,&k);
ans=0;
query(1, 1, n);
printf("%d\n", ans);
}
else{
scanf("%d%d%d",&ql,&qr,&v);
updata(1, 1, n);
}
}
}
int main(void)
{
while(scanf("%d%d",&n,&m), n!=0 || m!=0){
init();
solve();
}
return 0;
}