四种操作。
1.[L,R]范围内的数全部+c
2.[L,R]范围内的数全部*c
3.[L,R]范围内的数全部变为c
4.输出[L,R]范围内的数的k次方和(1 <= k <= 3 )
#include
#include
#include
using namespace std ;
#define lson l , m , o << 1
#define rson m + 1 , r , o << 1 | 1
const int mod = 10007 ;
const int maxN = 500000 ;
int sum1[maxN] , sum2[maxN] , sum3[maxN] ;
int add[maxN] , mul[maxN] , set[maxN] ;
void PushUp ( int o )
{
sum1[o] = ( sum1[o << 1] + sum1[o << 1 | 1] ) % mod ;
sum2[o] = ( sum2[o << 1] + sum2[o << 1 | 1] ) % mod ;
sum3[o] = ( sum3[o << 1] + sum3[o << 1 | 1] ) % mod ;
}
void PushDown ( int o , int l , int r )
{
int m = ( l + r ) >> 1 ;
if ( set[o] )
{
set[o << 1] = set[o << 1 | 1] = set[o] ;
add[o << 1] = add[o << 1 | 1] = 0 ;
mul[o << 1] = mul[o << 1 | 1] = 1 ;
sum1[o << 1] = ( m - l + 1 ) * set[o] % mod ;
sum2[o << 1] = sum1[o << 1] * set[o] % mod ;
sum3[o << 1] = sum2[o << 1] * set[o] % mod ;
sum1[o << 1 | 1] = ( r - m ) * set[o] % mod ;
sum2[o << 1 | 1] = sum1[o << 1 | 1] * set[o] % mod ;
sum3[o << 1 | 1] = sum2[o << 1 | 1] * set[o] % mod ;
set[o] = 0 ;
}
if ( add[o] || mul[o] != 1 )
{
add[o << 1] = ( add[o << 1] * mul[o] + add[o] ) % mod ;
mul[o << 1] = mul[o << 1] * mul[o] % mod ;
add[o << 1 | 1] = ( add[o << 1 | 1] * mul[o] + add[o] ) % mod ;
mul[o << 1 | 1] = mul[o << 1 | 1] * mul[o] % mod ;
int _sum1 , _sum2 , _sum3 ;
_sum1 = ( sum1[o << 1] * mul[o] % mod + add[o] * ( m - l + 1 ) % mod ) % mod ;
_sum2 = ( mul[o] * mul[o] % mod * sum2[o << 1] % mod
+ 2 * add[o] % mod * mul[o] % mod * sum1[o << 1] % mod
+ add[o] * add[o] % mod * ( m - l + 1 ) % mod ) % mod ;
_sum3 = ( mul[o] * mul[o] % mod * mul[o] % mod * sum3[o << 1] % mod
+ 3 * mul[o] % mod * mul[o] % mod * add[o] % mod * sum2[o << 1] % mod
+ 3 * mul[o] % mod * add[o] % mod * add[o] % mod * sum1[o << 1] % mod
+ add[o] * add[o] % mod * add[o] % mod * ( m - l + 1 ) % mod ) % mod ;
sum1[o << 1] = _sum1 ;
sum2[o << 1] = _sum2 ;
sum3[o << 1] = _sum3 ;
_sum1 = ( sum1[o << 1 | 1] * mul[o] % mod + add[o] * ( r - m ) % mod ) % mod ;
_sum2 = ( mul[o] * mul[o] % mod * sum2[o << 1 | 1] % mod
+ 2 * add[o] % mod * mul[o] % mod * sum1[o << 1 | 1] % mod
+ add[o] * add[o] % mod * ( r - m ) % mod ) % mod ;
_sum3 = ( mul[o] * mul[o] % mod * mul[o] % mod * sum3[o << 1 | 1] % mod
+ 3 * mul[o] % mod * mul[o] % mod * add[o] % mod * sum2[o << 1 | 1] % mod
+ 3 * mul[o] % mod * add[o] % mod * add[o] % mod * sum1[o << 1 | 1] % mod
+ add[o] * add[o] % mod * add[o] % mod * ( r - m ) % mod ) % mod ;
sum1[o << 1 | 1] = _sum1 ;
sum2[o << 1 | 1] = _sum2 ;
sum3[o << 1 | 1] = _sum3 ;
add[o] = 0 ;
mul[o] = 1 ;
}
}
void Build ( int l , int r , int o )
{
sum1[o] = sum2[o] = sum3[o] = 0 ;
add[o] = set[o] = 0 ;
mul[o] = 1 ;
if ( l == r ) return ;
int m = ( l + r ) >> 1 ;
Build ( lson ) ;
Build ( rson ) ;
}
void Update ( int ch , int v , int L , int R , int l , int r , int o )
{
if ( L <= l && r <= R )
{
int len = r - l + 1 ;
if ( 1 == ch )
{
add[o] = ( add[o] + v ) % mod ;
int _sum1 , _sum2 , _sum3 ;
_sum1 = ( sum1[o] + v * len ) % mod ;
_sum2 = ( sum2[o] + 2 * sum1[o] % mod * v % mod + v * v % mod * len % mod ) % mod ;
_sum3 = ( sum3[o] + 3 * v % mod * v % mod * sum1[o] % mod
+ 3 * v % mod * sum2[o] % mod + v * v % mod * v % mod * len % mod ) % mod ;
sum1[o] = _sum1 ;
sum2[o] = _sum2 ;
sum3[o] = _sum3 ;
}
if ( 2 == ch )
{
mul[o] = mul[o] * v % mod ;
add[o] = add[o] * v % mod ;
sum1[o] = sum1[o] * v % mod ;
sum2[o] = sum2[o] * v % mod * v % mod ;
sum3[o] = sum3[o] * v % mod * v % mod * v % mod ;
}
if ( 3 == ch )
{
set[o] = v ;
add[o] = 0 ;
mul[o] = 1 ;
sum1[o] = v * len % mod ;
sum2[o] = v * sum1[o] % mod ;
sum3[o] = v * sum2[o] % mod ;
}
return ;
}
PushDown ( o , l , r ) ;
int m = ( l + r ) >> 1 ;
if ( L <= m ) Update ( ch , v , L , R , lson ) ;
if ( m < R ) Update ( ch , v , L , R , rson ) ;
PushUp ( o ) ;
}
int Query ( int v , int L , int R , int l , int r , int o )
{
if ( L <= l && r <= R )
{
if ( 1 == v ) return sum1[o] ;
if ( 2 == v ) return sum2[o] ;
if ( 3 == v ) return sum3[o] ;
}
PushDown ( o , l , r ) ;
int ans = 0 , m = ( l + r ) >> 1 ;
if ( L <= m ) ans = ( ans + Query ( v , L , R , lson ) ) % mod ;
if ( m < R ) ans = ( ans + Query ( v , L , R , rson ) ) % mod ;
return ans ;
}
void work ()
{
int n , m , ch , v , l , r ;
while ( ~scanf ( "%d%d" , &n , &m ) && ( n || m ) )
{
Build ( 1 , n , 1 ) ;
while ( m -- )
{
scanf ( "%d%d%d%d" , &ch , &l , &r , &v ) ;
if ( ch == 4 )
{
int ans = Query ( v , l , r , 1 , n , 1 ) ;
printf ( "%d\n" , ans ) ;
}
else Update ( ch , v , l , r , 1 , n , 1 ) ;
}
}
}
int main ()
{
work () ;
return 0 ;
}