bzoj 1798
来源:互联网 发布:vb.net实例 编辑:程序博客网 时间:2024/06/06 04:14
题意:给出一个数列,支持三个操作。1.一个区间内所有数加上x 2.一个区间内所有数乘上x 3.询问一个区间内所有数的和。
分析:不同于区间和,还要标记一个乘法。对于每一个线段树上的点,标记两个数组mul(乘),val(加)。
(ax+b)*e+f=a*e*x+b*e+f
技能:
void pushdown(ll root,ll len)
{
if ((mul[root]-1) || val[root])
{
mul[root<<1]=mul[root]*mul[root<<1]%p; //对于儿子的mul标记直接乘上当前的mul
val[root<<1]=(val[root]+val[root<<1]*mul[root]%p)%p;
sum[root<<1]=(sum[root<<1]*mul[root]%p+val[root]*(len-(len>>1))%p)%p;//儿子的sum直接更新
mul[root<<1|1]=mul[root]*mul[root<<1|1]%p;
val[root<<1|1]=(val[root]+val[root<<1|1]*mul[root]%p)%p;
sum[root<<1|1]=(sum[root<<1|1]*mul[root]%p+val[root]*(len>>1)%p)%p;
mul[root]=1,val[root]=0;
}
}
代码:
#include<bits/stdc++.h>
using namespace std;#define ll long long
#define N 150010
#define rep(i,a,b) for (ll i=a;i<=b;++i)
ll mul[N<<2],sum[N<<2],val[N<<2],n,p,m;
ll read()
{
ll f=1,x=0;char ch=getchar();
for (;ch>'9'||ch<'0';ch=getchar()) if (ch=='-') f=-1;
for (;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';
return x*f;
}
void pushdown(ll root,ll len)
{
if ((mul[root]-1) || val[root])
{
mul[root<<1]=mul[root]*mul[root<<1]%p;
val[root<<1]=(val[root]+val[root<<1]*mul[root]%p)%p;
sum[root<<1]=(sum[root<<1]*mul[root]%p+val[root]*(len-(len>>1))%p)%p;
mul[root<<1|1]=mul[root]*mul[root<<1|1]%p;
val[root<<1|1]=(val[root]+val[root<<1|1]*mul[root]%p)%p;
sum[root<<1|1]=(sum[root<<1|1]*mul[root]%p+val[root]*(len>>1)%p)%p;
mul[root]=1,val[root]=0;
}
}
void pushup(ll root)
{
sum[root]=(sum[root<<1]+sum[root<<1|1])%p;
}
void add(ll root,ll l,ll r,ll L,ll R,ll y)
{
if (L<=l&&r<=R)
{
(sum[root]+=(r-l+1)*y%p)%=p;
(val[root]+=y)%=p;
return;
}
pushdown(root,r-l+1);
ll mid=l+r>>1;
if (L<=mid) add(root<<1,l,mid,L,R,y);
if (mid<R) add(root<<1|1,mid+1,r,L,R,y);
pushup(root);
}
void Mul(ll root,ll l,ll r,ll L,ll R,ll y)
{
if (L<=l&&r<=R)
{
(sum[root]*=y)%=p;
(mul[root]*=y)%=p;
(val[root]*=y)%=p;
return;
}
pushdown(root,r-l+1);
ll mid=l+r>>1;
if (L<=mid) Mul(root<<1,l,mid,L,R,y);
if (mid<R) Mul(root<<1|1,mid+1,r,L,R,y);
pushup(root);
}
ll query(ll root,ll l,ll r,ll L,ll R)
{
if (L<=l&&r<=R) return sum[root];
pushdown(root,r-l+1);
ll mid=l+r>>1,ans=0;
if (L<=mid) (ans+=query(root<<1,l,mid,L,R))%=p;
if (mid<R) (ans+=query(root<<1|1,mid+1,r,L,R))%=p;
pushup(root);
return ans;
}
int main()
{
n=read(); p=read();
rep(i,0,(N<<2)-1) mul[i]=1;
rep(i,1,n)
{
ll x=read();
add(1,1,n,i,i,x);
}
m=read();
rep(i,1,m)
{
ll x=read();
if (x==1)
{
ll u=read(),v=read(),c=read();
Mul(1,1,n,u,v,c);
}
else if (x==2)
{
ll u=read(),v=read(),c=read();
add(1,1,n,u,v,c);
}
else
{
ll u=read(),v=read();
printf("%lld\n",query(1,1,n,u,v));
}
}
return 0;
}
阅读全文
0 0
- bzoj 1798
- bzoj 1798 线段树
- 【BZOJ 1798】维护序列
- BZOJ 1798 线段树
- BZOJ 1798, 维护序列
- bzoj 1798 线段树
- [BZOJ ]
- BZOJ****-****
- BZOJ
- BZOJ
- BZOJ
- BZOJ
- BZOJ
- BZOJ
- BZOJ
- BZOJ
- BZOJ
- BZOJ
- EXCEL导入
- 带有倒计时功能的button
- java中遍历Map方式
- HTML5学习之FileReader接口
- 《麦肯锡精英的谈判策略》 -豆瓣评分8.2
- bzoj 1798
- 【排序算法】堆排序
- Codeforces #722C: Destroying Array 题解
- POJ3259_通过SPFA算法计算负环的裸体
- MySQL中高级知识-查询截取分析
- set pyhon3
- 搭建公司wiki系统
- [bzoj1984]月下“毛景树” 树链剖分
- caffe环境搭建