http://acm.hdu.edu.cn/showproblem.php?pid=4578
#include <cstdio>
#include <deque>
#include <set>
#include <string>
#include <map>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long LL;
const int maxn = 100005;
const int mod = 10007;
#define ls(p) p<<1
#define rs(p) p<<1|1
struct tree{
int l,r;
int sum1;
int sum2;
int sum3;
int col1;
int col2;
int col3;
}t[maxn<<2];
int n,m;
int pow2(int p){
p %= mod;
return (p*p) % mod;
}
int pow3(int p){
p %= mod;
return ((p*p)%mod*p) % mod;
}
void pushup(int p){
t[p].sum1 = (t[ls(p)].sum1 + t[rs(p)].sum1) % mod;
t[p].sum2 = (t[ls(p)].sum2 + t[rs(p)].sum2) % mod;
t[p].sum3 = (t[ls(p)].sum3 + t[rs(p)].sum3) % mod;
}
void pushdown(int p){
if(t[p].col3){
t[ls(p)].col3 = t[rs(p)].col3 = t[p].col3;
t[ls(p)].col1 = t[rs(p)].col1 = 0;
t[ls(p)].col2 = t[rs(p)].col2 = 1;
t[ls(p)].sum1 = (t[ls(p)].r - t[ls(p)].l + 1) * t[ls(p)].col3 % mod;
t[ls(p)].sum2 = (t[ls(p)].r - t[ls(p)].l + 1) * pow2(t[ls(p)].col3) % mod;
t[ls(p)].sum3 = (t[ls(p)].r - t[ls(p)].l + 1) * pow3(t[ls(p)].col3) % mod;
t[rs(p)].sum1 = (t[rs(p)].r - t[rs(p)].l + 1) * t[rs(p)].col3 % mod;
t[rs(p)].sum2 = (t[rs(p)].r - t[rs(p)].l + 1) * pow2(t[rs(p)].col3) % mod;
t[rs(p)].sum3 = (t[rs(p)].r - t[rs(p)].l + 1) * pow3(t[rs(p)].col3) % mod;
t[p].col3 = 0;
}
if(t[p].col1 != 0 || t[p].col2 != 1){
t[ls(p)].col1 = (t[p].col2 * t[ls(p)].col1 % mod + t[p].col1) % mod;
t[ls(p)].col2 = t[p].col2 * t[ls(p)].col2 % mod;
int sum1,sum2,sum3;
sum1 = (t[ls(p)].sum1*t[p].col2%mod + (t[ls(p)].r - t[ls(p)].l + 1)*t[p].col1%mod)%mod;
sum2 = (t[p].col2 * t[p].col2 % mod * t[ls(p)].sum2 % mod + 2*t[p].col1*t[p].col2%mod * t[ls(p)].sum1%mod + (t[ls(p)].r - t[ls(p)].l + 1)*t[p].col1%mod*t[p].col1%mod)%mod;
sum3 = t[p].col2 * t[p].col2 % mod * t[p].col2 % mod * t[ls(p)].sum3 % mod;
sum3 = (sum3 + 3*t[p].col2 % mod * t[p].col2 % mod * t[p].col1 % mod * t[ls(p)].sum2) % mod;
sum3 = (sum3 + 3*t[p].col2 % mod * t[p].col1 % mod * t[p].col1 % mod * t[ls(p)].sum1) % mod;
sum3 = (sum3 + (t[ls(p)].r - t[ls(p)].l + 1)*t[p].col1%mod * t[p].col1 % mod * t[p].col1 % mod) % mod;
t[ls(p)].sum1 = sum1;
t[ls(p)].sum2 = sum2;
t[ls(p)].sum3 = sum3;
t[rs(p)].col1 = (t[p].col2 * t[rs(p)].col1 % mod + t[p].col1) % mod;
t[rs(p)].col2 = t[p].col2 * t[rs(p)].col2 % mod;
sum1 = (t[rs(p)].sum1*t[p].col2%mod + (t[rs(p)].r - t[rs(p)].l + 1)*t[p].col1%mod)%mod;
sum2 = (t[p].col2 * t[p].col2 % mod * t[rs(p)].sum2 % mod + 2*t[p].col1*t[p].col2%mod * t[rs(p)].sum1%mod + (t[rs(p)].r - t[rs(p)].l + 1)*t[p].col1%mod*t[p].col1%mod)%mod;
sum3 = t[p].col2 * t[p].col2 % mod * t[p].col2 % mod * t[rs(p)].sum3 % mod;
sum3 = (sum3 + 3*t[p].col2 % mod * t[p].col2 % mod * t[p].col1 % mod * t[rs(p)].sum2) % mod;
sum3 = (sum3 + 3*t[p].col2 % mod * t[p].col1 % mod * t[p].col1 % mod * t[rs(p)].sum1) % mod;
sum3 = (sum3 + (t[rs(p)].r - t[rs(p)].l + 1)*t[p].col1%mod * t[p].col1 % mod * t[p].col1 % mod) % mod;
t[rs(p)].sum1 = sum1;
t[rs(p)].sum2 = sum2;
t[rs(p)].sum3 = sum3;
t[p].col1 = 0;
t[p].col2 = 1;
}
}
void build(int l,int r,int p){
t[p].l = l;
t[p].r = r;
t[p].sum1 = t[p].sum2 = t[p].sum3 = 0;
t[p].col1 = t[p].col2 = t[p].col3 = 0;
if(l == r)return;
int m = (l + r) >> 1;
build(l,m,ls(p));
build(m+1,r,rs(p));
}
void update1(int L,int R,int p,int c){
int l = t[p].l;
int r = t[p].r;
if(L<=l && r<=R){
t[p].col1 += c;
t[p].col1 %= mod;
t[p].sum3 = (t[p].sum3 + 3*t[p].sum2%mod*c%mod + 3*t[p].sum1%mod*c%mod*c%mod + (r - l + 1)*c%mod*c%mod*c%mod)%mod;
t[p].sum2 = (t[p].sum2 + 2*t[p].sum1%mod*c%mod + (r - l + 1)*c%mod*c%mod)%mod;
t[p].sum1 = (t[p].sum1 + (r - l + 1)*c%mod)%mod;
return;
}
pushdown(p);
int m = (l + r) >> 1;
if(L <= m)update1(L,R,ls(p),c);
if(R > m)update1(L,R,rs(p),c);
pushup(p);
}
void update2(int L,int R,int p,int c){
int l = t[p].l;
int r = t[p].r;
if(L<=l && r<=R){
t[p].col1 = t[p].col1*c%mod;
t[p].col2 = t[p].col2*c%mod;
t[p].sum3 = t[p].sum3*pow3(c)%mod;
t[p].sum2 = t[p].sum2*pow2(c)%mod;
t[p].sum1 = t[p].sum1*c%mod;
return;
}
pushdown(p);
int m = (l + r) >> 1;
if(L <= m)update2(L,R,ls(p),c);
if(R > m)update2(L,R,rs(p),c);
pushup(p);
}
void update3(int L,int R,int p,int c){
int l = t[p].l;
int r = t[p].r;
if(L<=l && r<=R){
t[p].col3 = c;
t[p].col1 = 0;
t[p].col2 = 1;
t[p].sum3 = (r-l+1)*pow3(c)%mod;
t[p].sum2 = (r-l+1)*pow2(c)%mod;
t[p].sum1 = (r-l+1)*c%mod;
return;
}
pushdown(p);
int m = (l + r) >> 1;
if(L <= m)update3(L,R,ls(p),c);
if(R > m)update3(L,R,rs(p),c);
pushup(p);
}
int query1(int L, int R,int p){
int l = t[p].l;
int r = t[p].r;
if(L <= l && r <= R){
return t[p].sum1;
}
pushdown(p);
int m = (l+r) >> 1;
int ans = 0;
if(m >= L)ans = (ans + query1(L,R,ls(p)))%mod;
if(m < R)ans = (ans + query1(L,R,rs(p)))%mod;
return ans;
}
int query2(int L,int R,int p){
int l = t[p].l;
int r = t[p].r;
if(L <= l && r <= R){
return t[p].sum2;
}
pushdown(p);
int m = (l+r) >> 1;
int ans = 0;
if(m >= L)ans = (ans + query2(L,R,ls(p)))%mod;
if(m < R)ans = (ans + query2(L,R,rs(p)))%mod;
return ans;
}
int query3(int L,int R,int p){
int l = t[p].l;
int r = t[p].r;
if(L <= l && r <= R){
return t[p].sum3;
}
pushdown(p);
int m = (l+r) >> 1;
int ans = 0;
if(m >= L)ans = (ans + query3(L,R,ls(p)))%mod;
if(m < R)ans = (ans + query3(L,R,rs(p)))%mod;
return ans;
}
int main(){
while(scanf("%d%d",&n,&m),n||m){
build(1,n,1);
while(m --){
int a,b,c,d;
scanf("%d%d%d%d",&a,&b,&c,&d);
if(a == 1){
update1(b,c,1,d);
}
else if(a == 2){
update2(b,c,1,d);
}
else if(a == 3){
update3(b,c,1,d);
}
else if(a == 4){
int ans;
if(d == 1){
ans = query1(b,c,1);
}
else if(d == 2){
ans = query2(b,c,1);
}
else if(d == 3){
ans = query3(b,c,1);
}
printf("%d\n",ans);
}
}
}
return 0;
}