//长度为n的数组 四个操作
//1 x y c [x,y]区间的数都加c
//2 x y c [x, y] 区间的数都乘以c
//3 x y c [x ,y] 区间的数都变为c
//4 x y p [x ,y] 求区间的数的p次方的和
//用线段树维护里面的值都相等的区间 ,那么这个区间的所需答案为(r-l+1)*(tree[v].eq)^q
//对于懒惰操作 mul , eq , add的处理是
//对于每次eq操作可以直接操作tree[v].eq = eq ;tree[v].mul = 1 ; tree[v].add = 0;
//而对于mul ,和add的操作每次push_down(v)的时候保证下面一层的所有懒惰情况都是初始情况
//所以对于mul和add操作时就一直往下push_down知道找到一个可以
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int maxn = 100010 ;
#define left v<<1
#define right v<<1|1
#define mod 10007
struct node
{
int l ,r , value ;
int eq , add , mul ;
}tree[maxn<<2];
void build(int l , int r , int v)
{
tree[v].l = l ;
tree[v].r = r ;
tree[v].add = 0 ; tree[v].mul = 1 ;tree[v].eq = -1 ;
if(l == r)
{tree[v].eq = 0 ; return ;}
int mid = (l + r) >> 1 ;
build(l , mid , left) ;
build(mid + 1 , r , right) ;
}
void push_down(int v)
{
if(tree[v].l == tree[v].r)return ;
if(tree[v].eq != -1)
{
tree[left].eq = tree[right].eq = tree[v].eq ;
tree[left].add = tree[right].add = 0 ;
tree[left].mul = tree[right].mul = 1;
tree[v].eq = -1;
return ;
}
if(tree[v].mul != 1)
{
if(tree[left].eq != -1)
tree[left].eq = (tree[left].eq*tree[v].mul)%mod ;
else
{
push_down(left) ;
tree[left].mul = (tree[left].mul*tree[v].mul)%mod ;
}
if(tree[right].eq != -1)
tree[right].eq = (tree[right].eq*tree[v].mul)%mod ;
else
{
push_down(right) ;
tree[right].mul = (tree[right].mul*tree[v].mul)%mod ;
}
tree[v].mul = 1;
}
if(tree[v].add)
{
if(tree[left].eq != -1)
tree[left].eq = (tree[left].eq + tree[v].add)%mod ;
else
{
push_down(left) ;
tree[left].add = (tree[left].add + tree[v].add)%mod ;
}
if(tree[right].eq != -1)
tree[right].eq = (tree[right].eq + tree[v].add)%mod ;
else
{
push_down(right) ;
tree[right].add = (tree[right].add + tree[v].add)%mod ;
}
tree[v].add = 0 ;
}
}
void update(int l , int r , int v , int op , int c)
{
if(l <= tree[v].l && tree[v].r <= r)
{
if(op == 3)
{
tree[v].add = 0 ;tree[v].mul = 1;
tree[v].eq = c ;
return ;
}
if(tree[v].eq != -1)
{
if(op == 1)tree[v].eq = (tree[v].eq + c)%mod ;
else tree[v].eq = (tree[v].eq*c)%mod ;
}
else
{
push_down(v) ;
if(op == 1)tree[v].add = (tree[v].add + c)%mod ;
else tree[v].mul = (tree[v].mul*c)%mod ;
}
return ;
}
push_down(v) ;
int mid = (tree[v].l + tree[v].r) >> 1 ;
if(l <= mid)update(l , r ,left , op , c) ;
if(r > mid)update(l , r , right , op , c) ;
}
int query(int l , int r , int v , int q)
{
if(tree[v].l >= l && tree[v].r <= r && tree[v].eq != -1)
{
int ans = 1;
for(int i = 1;i <= q;i++)
ans = (ans * tree[v].eq)%mod ;
return (ans*((tree[v].r - tree[v].l + 1)%mod))%mod ;
}
push_down(v) ;
int mid = (tree[v].l + tree[v].r) >> 1 ;
if(l > mid)return query(l , r , right, q) ;
else if(r <= mid)return query(l , r ,left ,q) ;
else return (query(l , mid , left , q) + query(mid + 1 , r , right , q))%mod ;
}
int main()
{
//freopen("in.txt" ,"r" , stdin) ;
int n , m ;
while(scanf("%d%d" , &n , &m) &&(n+m))
{
int op , x , y , c;
build(1 , n , 1) ;
while(m--)
{
scanf("%d%d%d%d" , &op , &x , &y , &c) ;
if(op == 4)
printf("%d\n" , (query(x, y , 1 , c)%mod)) ;
else update(x , y , 1 , op , c) ;
}
}
return 0 ;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。