简单的线段树,三种操作所以使用三种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;  
}