智乃酱有n个cube(立方体),一开始,这些立方体的长宽高均为1,也就是它们的体积都为1×1×1=1,并且这些立方体从1到n排成一排。
接下来智乃酱将要进行m次操作。智乃酱可以将l到r这个区间内所有的立方体某个维度增加a,或者向你询问从l到r中所有立方体的体积之和。
由于这个数字比较大,所以每次查询时你只用输出从l到r中所有立方体的体积之和mod 10^9+7后的结果即可。
链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
第一行输入两个正整数n,m(1≤n≤10^5,1≤m≤4×10^5)表示区间的长度与操作的数目。 接下来m行,每行首先输入一个字符表示操作的类型。 当输入的字符为′x′时,还需输入三个整数l,r,a(1≤l≤r≤n,1≤a≤10^9)表示对l到r中所有立方体的x轴上的边的边长增加a。 当输入的字符为′y′时,还需输入三个整数l,r,a(1≤l≤r≤n,1≤a≤10^9)表示对l到r中所有立方体的y轴上的边的边长增加a。 当输入的字符为′z′时,还需输入三个整数l,r,a(1≤l≤r≤n,1≤a≤10^9)l,r,a表示对l到r中所有立方体的z轴上的边的边长增加a{a}a。 当输入的字符为′q′时,还需输入两个整数l,r(1≤l≤r≤n)l表示查询l到r中所有立方体的体积之和mod 10^9+7后的结果。 输入保证至少进行了一次查询操作。
对于每个查询操作,输出l到r中所有立方体的体积之和mod 10^9+7后的结果。
示例1
5 9 x 1 3 1 y 2 4 1 q 1 5 z 3 5 1 q 1 5 x 1 5 1 y 1 5 1 z 1 5 1 q 1 5
13 20 87
#include
using namespace std;
#define int long long
const int N=1e5+10;
const int mod=1e9+7;
int n,m;
int add(int a,int b)
{
return (a+b)%mod;
}
int sub(int a,int b)
{
return ((a-b)%mod+mod)%mod;
}
int mul(int a,int b)
{
return a*b%mod;
}
struct node
{
int lza,lzb,lzc;
int x,y,z,xy,xz,yz,xyz;
} t[N*4];
void pushdown(int i,int l,int r)
{
if(t[i].lza)
{
int k=t[i].lza;
int mid=(l+r)>>1;
int f1=mid-l+1,f2=r-mid;
t[i<<1].xyz=add(t[i<<1].xyz,mul(t[i<<1].yz,k));
t[i<<1|1].xyz=add(t[i<<1|1].xyz,mul(t[i<<1|1].yz,k));
t[i<<1].xy=add(t[i<<1].xy,mul(t[i<<1].y,k));
t[i<<1|1].xy=add(t[i<<1|1].xy,mul(t[i<<1|1].y,k));
t[i<<1].xz=add(t[i<<1].xz,mul(t[i<<1].z,k));
t[i<<1|1].xz=add(t[i<<1|1].xz,mul(t[i<<1|1].z,k));
t[i<<1].x=add(t[i<<1].x,mul(f1,k));
t[i<<1|1].x=add(t[i<<1|1].x,mul(f2,k));
t[i<<1].lza=add(t[i<<1].lza,k);
t[i<<1|1].lza=add(t[i<<1|1].lza,k);
t[i].lza=0;
//return;
}
if(t[i].lzb)
{
int k=t[i].lzb;
int mid=(l+r)>>1;
int f1=mid-l+1,f2=r-mid;
t[i<<1].xyz=add(t[i<<1].xyz,mul(t[i<<1].xz,k));
t[i<<1|1].xyz=add(t[i<<1|1].xyz,mul(t[i<<1|1].xz,k));
t[i<<1].xy=add(t[i<<1].xy,mul(t[i<<1].x,k));
t[i<<1|1].xy=add(t[i<<1|1].xy,mul(t[i<<1|1].x,k));
t[i<<1].yz=add(t[i<<1].yz,mul(t[i<<1].z,k));
t[i<<1|1].yz=add(t[i<<1|1].yz,mul(t[i<<1|1].z,k));
t[i<<1].y=add(t[i<<1].y,mul(f1,k));
t[i<<1|1].y=add(t[i<<1|1].y,mul(f2,k));
t[i<<1].lzb=add(t[i<<1].lzb,k);
t[i<<1|1].lzb=add(t[i<<1|1].lzb,k);
t[i].lzb=0;
//return;
}
if(t[i].lzc)
{
int k=t[i].lzc;
int mid=(l+r)>>1;
int f1=mid-l+1,f2=r-mid;
t[i<<1].xyz=add(t[i<<1].xyz,mul(t[i<<1].xy,k));
t[i<<1|1].xyz=add(t[i<<1|1].xyz,mul(t[i<<1|1].xy,k));
t[i<<1].yz=add(t[i<<1].yz,mul(t[i<<1].y,k));
t[i<<1|1].yz=add(t[i<<1|1].yz,mul(t[i<<1|1].y,k));
t[i<<1].xz=add(t[i<<1].xz,mul(t[i<<1].x,k));
t[i<<1|1].xz=add(t[i<<1|1].xz,mul(t[i<<1|1].x,k));
t[i<<1].z=add(t[i<<1].z,mul(f1,k));
t[i<<1|1].z=add(t[i<<1|1].z,mul(f2,k));
t[i<<1].lzc=add(t[i<<1].lzc,k);
t[i<<1|1].lzc=add(t[i<<1|1].lzc,k);
t[i].lzc=0;
//return;
}
}
void pushup(int i)
{
t[i].x=add(t[i<<1].x,t[i<<1|1].x);
t[i].y=add(t[i<<1].y,t[i<<1|1].y);
t[i].z=add(t[i<<1].z,t[i<<1|1].z);
t[i].xy=add(t[i<<1].xy,t[i<<1|1].xy);
t[i].xz=add(t[i<<1].xz,t[i<<1|1].xz);
t[i].yz=add(t[i<<1].yz,t[i<<1|1].yz);
t[i].xyz=add(t[i<<1].xyz,t[i<<1|1].xyz);
}
void build(int i,int l,int r)
{
t[i].lza=t[i].lzb=t[i].lzc=0;
if(l==r)
{
t[i].x=t[i].y=t[i].z=t[i].xy=t[i].xz=t[i].yz=t[i].xyz=1;
return;
}
int mid=(l+r)>>1;
build(i<<1,l,mid);
build(i<<1|1,mid+1,r);
pushup(i);
return;
}
void update(int rt,int l,int r,int L,int R,int type,int val)
{
if(L<=l&&r<=R)
{
if(type==1)
{
int k=val;
int f1=r-l+1;
t[rt].xyz=add(t[rt].xyz,mul(t[rt].yz,k));
t[rt].xy=add(t[rt].xy,mul(t[rt].y,k));
t[rt].xz=add(t[rt].xz,mul(t[rt].z,k));
t[rt].x=add(t[rt].x,mul(f1,k));
t[rt].lza=add(t[rt].lza,k);
return;
}
if(type==2)
{
int k=val;
int f1=r-l+1;
t[rt].xyz=add(t[rt].xyz,mul(t[rt].xz,k));
t[rt].xy=add(t[rt].xy,mul(t[rt].x,k));
t[rt].yz=add(t[rt].yz,mul(t[rt].z,k));
t[rt].y=add(t[rt].y,mul(f1,k));
t[rt].lzb=add(t[rt].lzb,k);
return;
}
if(type==3)
{
int k=val;
int f1=r-l+1;
t[rt].xyz=add(t[rt].xyz,mul(t[rt].xy,k));
t[rt].xz=add(t[rt].xz,mul(t[rt].x,k));
t[rt].yz=add(t[rt].yz,mul(t[rt].y,k));
t[rt].z=add(t[rt].z,mul(f1,k));
t[rt].lzc=add(t[rt].lzc,k);
return;
}
return ;
}
pushdown(rt,l,r);
int mid=(l+r)>>1;
if(L<=mid) update(rt<<1,l,mid,L,R,type,val);
if(R>mid)update(rt<<1|1,mid+1,r,L,R,type,val);
pushup(rt);
return;
}
int query(int rt,int l,int r,int L,int R)
{
if(L<=l&&R>=r)
{
return t[rt].xyz;
}
pushdown(rt,l,r);
int mid=(l+r)>>1;
int ans=0;
if(mid >= R) ans=add(ans,query(rt<<1, l, mid, L, R));
else if(mid < L) ans=add(ans,query(rt<<1|1, mid + 1, r, L, R));
else
{
ans=add(ans,add(query(rt<<1, l, mid, L, mid),query(rt<<1|1, mid + 1, r, mid + 1, R)));
}
return ans;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n>>m;
build(1,1,n);
for(int i=1; i<=m; i++)
{
char c;
cin>>c;
int l,r;
cin>>l>>r;
if(c=='x')
{
int a;
cin>>a;
update(1,1,n,l,r,1,a);
}
else if(c=='y')
{
int a;
cin>>a;
update(1,1,n,l,r,2,a);
}
else if(c=='z')
{
int a;
cin>>a;
update(1,1,n,l,r,3,a);
}
else
{
cout<