【题意】给定序列,支持区间加和区间乘,查询区间和取模。n<=10^5。

【算法】线段树

【题解】线段树多重标记要考虑标记与标记之间的相互影响。

对于sum*b+a,+c直接加上即可。

*c后就是(sum*b+a)*c=sum*b*b+a*c,也就是加法的部分也要乘。

所以,每次在乘法的时候要把加法标记也乘上。下传时先传乘法。

注意乘法初始值为1,但是取模后可能为0。

#include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>
using namespace std;
int read(){
int s=,t=;char c;
while(!isdigit(c=getchar()))if(c=='-')t=-;
do{s=s*+c-'';}while(isdigit(c=getchar()));
return s*t;
}
const int maxn=;
struct tree{int l,r,a,b,sum;}t[maxn*];
int n,MOD,a[maxn];
int M(int x){return x>=MOD?x-MOD:x;}
void up(int k){t[k].sum=M(t[k<<].sum+t[k<<|].sum);}
void modify_a(int k,int x){t[k].sum=M(t[k].sum+1ll*(t[k].r-t[k].l+)*x%MOD);t[k].a=M(t[k].a+x);}//
void modify_b(int k,int x){t[k].sum=1ll*t[k].sum*x%MOD;t[k].b=1ll*t[k].b*x%MOD;t[k].a=1ll*t[k].a*x%MOD;}
void down(int k){
if(t[k].b!=){//
modify_b(k<<,t[k].b);modify_b(k<<|,t[k].b);
t[k].b=;
}
if(t[k].a){
modify_a(k<<,t[k].a);modify_a(k<<|,t[k].a);
t[k].a=;
}
}
void build(int k,int l,int r){
t[k].l=l;t[k].r=r;t[k].a=;t[k].b=;
if(l==r){t[k].sum=a[l];return;}
int mid=(l+r)>>;
build(k<<,l,mid);build(k<<|,mid+,r);
up(k);
}
void add(int k,int l,int r,int x){
if(l<=t[k].l&&t[k].r<=r){modify_a(k,x);return;}
down(k);
int mid=(t[k].l+t[k].r)>>;//
if(l<=mid)add(k<<,l,r,x);
if(r>mid)add(k<<|,l,r,x);
up(k);
}
void mul(int k,int l,int r,int x){
if(l<=t[k].l&&t[k].r<=r){modify_b(k,x);return;}
down(k);
int mid=(t[k].l+t[k].r)>>;//
if(l<=mid)mul(k<<,l,r,x);
if(r>mid)mul(k<<|,l,r,x);
up(k);
}
int query(int k,int l,int r){
if(l<=t[k].l&&t[k].r<=r){return t[k].sum;}
down(k);
int mid=(t[k].l+t[k].r)>>,sum=;
if(l<=mid)sum=query(k<<,l,r);
if(r>mid)sum=M(sum+query(k<<|,l,r));
return sum;
}
int main(){
n=read();MOD=read();
for(int i=;i<=n;i++)a[i]=read()%MOD;
build(,,n);
int m=read();
while(m--){
int k=read(),x=read(),y=read();
if(k==){printf("%d\n",query(,x,y));continue;}
int z=read();
if(k==)mul(,x,y,z%MOD);else add(,x,y,z%MOD);
}
return ;
}

最新文章

  1. 可以ping通,但是不能connect
  2. 数据结构Java实现02----线性表与顺序表
  3. 用shell写个100以内的所有数字之和
  4. GridView導出Excel 解決亂碼問題
  5. 在MyEclipse中如何去掉JS或jsp语法错误提示!
  6. iOS之AlertController的使用
  7. c++ primer复习(四)
  8. 【算法】一般冒泡排序 O(n^2) 稳定的 C语言
  9. sql 数据库备份还原脚本
  10. deepin添加新的打开方式软件
  11. web压缩gzip响应
  12. 原生js写ajax请求(复习)
  13. poj-1207 THE 3n+1 problem
  14. STD函数的内部计算公式
  15. Tracing 在PeopleSoft 程序中怎么开启
  16. 【网络文摘】Androidguy:当你的才华还无法撑起你的野心时,那么应该静下心来学习
  17. 使用Dockerfile文件构建基于centOS系统的tomcat镜像
  18. 404 Note Found 队-Alpha4
  19. hdu 2527:Safe Or Unsafe(数据结构,哈夫曼树,求WPL)
  20. XVII Open Cup named after E.V. Pankratiev Stage 14, Grand Prix of Tatarstan, Sunday, April 2, 2017 Problem F. Matrix Game

热门文章

  1. 前端系列之HTML基础知识概述
  2. lintcode-408-二进制求和
  3. IOC 依赖注入 Unity
  4. SQL 语句(增删改查)
  5. 1029对c语言文法的理解
  6. 【BioCode】根据seq与位点信息截取窗口
  7. php中ob缓存机制
  8. C#中的静态常量(const)和动态常量(static和readonly)用法和区别
  9. hdu 6435 CSGO(最大曼哈顿距离)
  10. 【bzoj4542】[Hnoi2016]大数 莫队算法