题意:有一个序列,有四种操作:
1:区间[l,r]内的数全部加c。
2:区间[l,r]内的数全部乘c。
3:区间[l,r]内的数全部初始为c。
4:询问区间[l,r]内所有数的P次方之和。
每次更新到相同区间
#include "stdio.h"
#include "string.h"
#include "queue"
#include "vector"
#include "algorithm"
using namespace std;
const int maxn = 100005;
const int mod = 10007;
const int inf = 1<<30;
int n,m;
int op,x,y,p;
struct node
{
int num;
}tree[maxn<<2];
int Pow( int a,int x )
{
int ans = 1;
for( int i = 1; i <= x; i ++ )
{
ans = ( ans*a )%mod;
}
return ans;
}
void PushDown( int rt )
{
if( tree[rt].num != -1 )
{
tree[rt<<1].num = tree[rt<<1|1].num = tree[rt].num;
tree[rt].num = -1;
}
}
void BuildTree( int rt,int ld,int rd )
{
tree[rt].num = 0;
if( ld < rd )
{
int mid = ( ld+rd )>>1;
BuildTree( rt<<1,ld,mid );
BuildTree( rt<<1|1,mid+1,rd );
}
}
void updata( int rt,int ld,int rd )
{
if( x <= ld && rd <= y && ( op == 3 || tree[rt].num != -1 ) )
{
if( op == 1 )
{
tree[rt].num = (tree[rt].num + p)%mod;
}
else if( op == 2 )
{
tree[rt].num = (tree[rt].num * p)%mod;
}
else if( op == 3 )
{
tree[rt].num = p%mod;
}
return;
}
PushDown( rt );
int mid = ( ld+rd )>>1;
if( x <= mid ) updata( rt<<1,ld,mid );
if( y > mid ) updata( rt<<1|1,mid+1,rd );
}
int query( int rt,int ld,int rd )
{
if( x <= ld && rd <= y && tree[rt].num != -1 )
{
return Pow( tree[rt].num,p ) * ( rd - ld + 1 );
}
if( y < ld || x > rd ) return 0;
if( tree[rt].num != -1 )
tree[rt<<1].num = tree[rt<<1|1].num = tree[rt].num;
int mid = ( ld+rd )>>1;
return (query( rt<<1,ld,mid ) + query( rt<<1|1,mid+1,rd ))%mod;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("data.txt","r",stdin);
#endif
while( scanf("%d%d",&n,&m) != EOF,(n||m) )
{
BuildTree( 1,1,n );
for( int i = 0; i < m; i ++ )
{
scanf("%d%d%d%d",&op,&x,&y,&p);
if( op == 4 )
{
printf("%d\n",query( 1,1,n ));
}
else
updata( 1,1,n );
}
}
return 0;
}