从题面可以推断,如果一个区间中的值很可能为等于同一个值,即有操作涉及,对某个区间设为t之类,就很可能存在一个区间,区间值全部相等,就可以用线段树做标记,标记区间值,如果,区间中有值不相等则对其赋值为-1,注意如果区间值相等修改,或者查询时需要下推标记。
#include<bits/stdc++.h>
using namespace std;
int mod=10007;
int tr[200000*4];
void pushup(int i)
{
if(tr[i*2]!=tr[i*2+1])
tr[i]=-1;
else
{
tr[i]=tr[i*2];
}
}
void update(int i,int l,int r,int x,int y,int op,int t)
{
if(x<=l&&y>=r&&tr[i]!=-1)
{
if(op==1)
{
tr[i]+=t;
tr[i]%=mod;
}
else if(op==2)
{
tr[i]*=t;
tr[i]%=mod;
}
else
{
tr[i]=t;
tr[i]%=mod;
}
return ;
}
if(tr[i]!=-1)
{
tr[i*2]=tr[i*2+1]=tr[i];
}
int mid=l+r>>1;
if(x<=mid)
update(i*2,l,mid,x,y,op,t);
if(y>mid)
update(i*2+1,mid+1,r,x,y,op,t);
pushup(i);
}
int query(int i,int l,int r,int x,int y,int p)
{
if(x<=l&&y>=r&&tr[i]!=-1)
{
int sum=1;
for(int j=0;j<p;j++)
{
sum=(sum*tr[i])%mod;
}
sum=sum*(r-l+1);
sum%=mod;
// printf("%d\n",sum);
return sum;
}
if(tr[i]!=-1)
{
tr[i*2]=tr[i*2+1]=tr[i];
}
int mid=l+r>>1;
int ans=0;
if(x<=mid)
ans+=query(i*2,l,mid,x,y,p);
if(y>mid)
ans+=query(i*2+1,mid+1,r,x,y,p);
return ans%mod;
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
if(n==0&&m==0)
return 0;
int op,x,y,t;
memset(tr,0,sizeof(tr));
while(m--)
{
scanf("%d%d%d%d",&op,&x,&y,&t);
if(op<=3)
update(1,1,n,x,y,op,t);
else
printf("%d\n",query(1,1,n,x,y,t));
}
}
return 0;
}