bzoj 1798 线段树

来源:互联网 发布:软件测试培训三个月 编辑:程序博客网 时间:2024/05/22 03:49
#include<cstdio>#define N 500010#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1using namespace std;long long int t[N],add[N],mul[N],p;void build(int l,int r,int rt){add[rt]=0;mul[rt]=1;if(l==r){scanf("%d",&t[rt]);return ;}int m=(l+r)>>1;build(lson);build(rson);t[rt]=(t[rt<<1]+t[rt<<1|1])%p;} void pushdown(int l,int r,int rt){int m=(l+r)>>1;if(add[rt]!=0||mul[rt]!=1){add[rt<<1]=(add[rt<<1]*mul[rt]+add[rt])%p;add[rt<<1|1]=(add[rt<<1|1]*mul[rt]+add[rt])%p;mul[rt<<1]=(mul[rt<<1]*mul[rt])%p;mul[rt<<1|1]=(mul[rt<<1|1]*mul[rt])%p;t[rt<<1]=(t[rt<<1]*mul[rt]+add[rt]*(m-l+1))%p;t[rt<<1|1]=(t[rt<<1|1]*mul[rt]+add[rt]*(r-m))%p;add[rt]=0;mul[rt]=1;}}void update(int a,int b,int c,int v,int l,int r,int rt){if(a>r||b<l)return ;if(a<=l&&r<=b){if(c==1){add[rt]=(add[rt]*v)%p;mul[rt]=mul[rt]*v%p;t[rt]=t[rt]*v%p;}else{add[rt]=(add[rt]+v)%p;t[rt]=(t[rt]+(long long)v*(r-l+1))%p;}return ;}pushdown(l,r,rt);int m=(l+r)>>1;update(a,b,c,v,lson);update(a,b,c,v,rson);t[rt]=(t[rt<<1]+t[rt<<1|1])%p;}long long query(int a,int b,int l,int r,int rt){if(a>r||b<l)return 0;if(a<=l&&r<=b)return t[rt]%p;pushdown(l,r,rt);int m=(l+r)>>1;int res1=query(a,b,lson);int res2=query(a,b,rson);return (res1+res2)%p;}int main(){int n;scanf("%d%lld",&n,&p);build(1,n,1);int q;scanf("%d",&q);while(q--){int t,a,b,c;scanf("%d",&t);if(t!=3){int a,b,c;scanf("%d%d%d",&a,&b,&c);update(a,b,t,c,1,n,1);}else{scanf("%d%d",&a,&b);printf("%lld\n",query(a,b,1,n,1));}}}

原创粉丝点击