1 /*
2 lazy思想的运用,因为查询多种,如果全记录就太繁了,lazy就是如果该区间的每一个叶子的状态都相同就不用深入下去该值,只要暂时标记下,查询的时候也不用下去,直接计算;
3
4 */
5 #include<iostream>
6 #include<cstdio>
7 #include<cstring>
8 #include<algorithm>
9 #define MAX_N 100005
10 #define mod 10007
11 #define ll long long
12 using namespace std;
13 struct tree
14 {
15 ll l,r,la[4];
16 ll same,s;//s表示该区间的值都是s;
17 }tr[MAX_N*4];
18 ll ans=0;
19 void build(int rt,int l,int r)
20 {
21 tr[rt].l=l;
22 tr[rt].r=r;
23 tr[rt].same=1;
24 tr[rt].s=0;
25 memset(tr[rt].la,0,sizeof(tr[rt].la));
26 tr[rt].la[2]=1;
27 if(l==r)
28 return ;
29 int mid=(l+r)/2;
30 build(rt<<1,l,mid);
31 build(rt<<1|1,mid+1,r);
32 }
33 void Pushdown(int rt)
34 {
35 if(tr[rt].same==1)
36 {
37 int L=rt<<1,R=rt<<1|1;
38 tr[L].la[1]+=tr[rt].la[1];
39 tr[L].la[2]*=tr[rt].la[2];
40 tr[L].la[3]=tr[rt].la[3];
41 tr[L].s=tr[R].s=tr[rt].s;
42 tr[R].la[1]+=tr[rt].la[1];
43 tr[R].la[2]*=tr[rt].la[2];
44 tr[R].la[3]=tr[rt].la[3];
45 tr[L].same=tr[R].same=1;
46 tr[rt].la[1]=0;
47 tr[rt].la[2]=1;
48 tr[rt].la[3]=0;
49 tr[rt].same=0;
50 }
51 return;
52 }
53 void Update(int rt,int l,int r,int x,int t)
54 {
55 if(t==1)
56 {
57 if(tr[rt].l==l&&tr[rt].r==r&&tr[rt].same==1)
58 {
59 tr[rt].la[1]+=x;//关键;
60 tr[rt].la[1]%=mod;
61 tr[rt].s=tr[rt].s+x;
62 return ;
63 }
64 }
65 else if(t==2)
66 {
67 if(tr[rt].l==l&&tr[rt].r==r&&tr[rt].same==1)
68 {
69 tr[rt].la[2]*=x;
70 tr[rt].la[2]%=mod;
71 tr[rt].s=tr[rt].s*x%mod;
72 return ;
73 }
74 }
75 else
76 {
77 if(tr[rt].l==l&&tr[rt].r==r)
78 {
79 tr[rt].la[3]=x;
80 tr[rt].s=x;
81 tr[rt].same=1;
82 return;
83 }
84 }
85 if(tr[rt].same==1)
86 Pushdown(rt);
87 int L=rt<<1,R=rt<<1|1;
88 if(l<=tr[L].r)
89 {
90 if(r<=tr[L].r)
91 Update(L,l,r,x,t);
92 else
93 Update(L,l,tr[L].r,x,t);
94 }
95 if(r>=tr[R].l)
96 {
97 if(l>=tr[R].l)
98 Update(R,l,r,x,t);
99 else
100 Update(R,tr[R].l,r,x,t);
101 }
102 }
103 void Query(int rt,int l,int r,int x)
104 {
105 if(tr[rt].l==l&&tr[rt].r==r&&tr[rt].same==1)
106 {
107 ll n=r-l+1,temp=1;
108 for(int i=1;i<=x;i++)
109 {
110 temp*=tr[rt].s%mod;
111 temp%=mod;
112 }
113 ans+=(temp*n%mod)%mod;
114 return ;
115 }
116 if(tr[rt].same==1)
117 Pushdown(rt);
118 int L=rt<<1,R=rt<<1|1;
119 if(l<=tr[L].r)
120 {
121 if(r<=tr[L].r)
122 Query(L,l,r,x);
123 else
124 Query(L,l,tr[L].r,x);
125 }
126 if(r>=tr[R].l)
127 {
128 if(l>=tr[R].l)
129 Query(R,l,r,x);
130 else
131 Query(R,tr[R].l,r,x);
132 }
133 }
134 int main()
135 {
136 int n,m;
137 while(scanf("%d%d",&n,&m)!=EOF&&(n||m))
138 {
139 memset(tr,0,sizeof(tr));
140 build(1,1,n);
141 for(int i=0;i<m;i++)
142 {
143 int x,y,ty,c;
144 scanf("%d%d%d%d",&ty,&x,&y,&c);
145 if(ty==4)
146 {
147 ans=0;
148 Query(1,x,y,c);
149 cout<<ans%mod<<endl;
150 }
151 else
152 {
153 Update(1,x,y,c,ty);
154 }
155
156 }
157 }
158 return 0;
159 }