题目大意:有$n$个数,有$m$个操作,有三种:

  1. $1\;l\;r\;x:$把区间$[l,r]$内的数乘上$x$
  2. $2\;l\;r\;x:$把区间$[l,r]$内的数加上$x$
  3. $3\;l\;r:$询问区间$[l,r]$的和,对$p$取模

(线段树2就是先读入$n\;m\;p$,再读入序列;本题是先读入$n\;p$,读入序列,再读入$m$,双倍经验)

题解:线段树,把$lazy\_tag$变成两个,分别记录区间加和区间乘,注意乘法的优先级比加法高

卡点:无(我以前写的是什么代码啊?)

C++ Code:

#include <cstdio>
#define maxn 100010 << 2
long long V[maxn], cov[maxn], tg[maxn];
int n, m;
int s[maxn], L, R;
long long p, x;
void update(int rt) {
V[rt] = (V[rt << 1] + V[rt << 1 | 1]) % p;
}
void build(int rt, int l, int r) {
cov[rt] = 1;
if (l == r) {
V[rt] = s[l] % p;
return ;
}
int mid = l + r >> 1;
build(rt << 1, l, mid);
build(rt << 1 | 1, mid + 1, r);
update(rt);
}
void pushdown(int rt, long long len) {
long long &Cov = cov[rt], &Tg = tg[rt];
V[rt << 1] = (V[rt << 1] * Cov + Tg * (len + 1 >> 1)) % p;
V[rt << 1 | 1] = (V[rt << 1 | 1] * Cov + Tg * (len >> 1)) % p;
cov[rt << 1] = (cov[rt << 1] * Cov) % p;
cov[rt << 1 | 1] = (cov[rt << 1 | 1] * Cov) % p;
tg[rt << 1] = (tg[rt << 1] * Cov + Tg) % p;
tg[rt << 1 | 1] = (tg[rt << 1 | 1] * Cov + Tg) % p;
Cov = 1, Tg = 0;
}
void add1(int rt, int l, int r) {
if (L <= l && R >= r) {
V[rt] = (V[rt] * x) % p;
cov[rt] = (cov[rt] * x) % p;
tg[rt] = (tg[rt] * x) % p;
return ;
}
int mid = l + r >> 1;
if (cov[rt] != 1 || tg[rt]) pushdown(rt, r - l + 1);
if (L <= mid) add1(rt << 1, l, mid);
if (R > mid) add1(rt << 1 | 1, mid + 1, r);
update(rt);
}
void add2(int rt, int l, int r) {
if (L <= l && R >= r) {
V[rt] = (V[rt] + x * (r - l + 1ll)) % p;
tg[rt] = (tg[rt] + x) % p;
return ;
}
int mid = l + r >> 1;
if (cov[rt] != 1 || tg[rt]) pushdown(rt, r - l + 1);
if (L <= mid) add2(rt << 1, l, mid);
if (R > mid) add2(rt << 1 | 1, mid + 1, r);
update(rt);
}
long long ask(int rt, int l, int r) {
if (L <= l && R >= r) return V[rt] % p;
int mid = l + r >> 1;
long long ans = 0;
if (cov[rt] != 1 || tg[rt]) pushdown(rt, r - l + 1);
if (L <= mid) ans = ask(rt << 1, l, mid);
if (R > mid) ans = (ans + ask(rt << 1 | 1, mid + 1, r)) % p;
return ans;
}
int main() {
scanf("%d%lld", &n, &p);
for (int i = 1; i <= n; i++) scanf("%d", s + i);
build(1, 1, n);
scanf("%d", &m);
while (m --> 0) {
long long op;
scanf("%lld%d%d", &op, &L, &R);
switch (op) {
case 1: {
scanf("%lld", &x);
add1(1, 1, n);
break;
}
case 2: {
scanf("%lld", &x);
add2(1, 1, n);
break;
}
default: printf("%lld\n", ask(1, 1, n));
}
}
return 0;
}

[bzoj1798][Ahoi2009]Seq 维护序列seq ([洛谷P3373]【模板】线段树 2)的更多相关文章

  1. 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)

    To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...

  2. BZOJ1798: [Ahoi2009]Seq 维护序列seq[线段树]

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 5504  Solved: 1937[Submit ...

  3. BZOJ 1798: [Ahoi2009]Seq 维护序列seq( 线段树 )

    线段树.. 打个 mul , add 的标记就好了.. 这个速度好像还挺快的...( 相比我其他代码 = = ) 好像是#35.. ---------------------------------- ...

  4. 1798: [Ahoi2009]Seq 维护序列seq

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 2930  Solved: 1087[Submit ...

  5. bzoj 1798: [Ahoi2009]Seq 维护序列seq (线段树 ,多重标记下放)

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 7773  Solved: 2792[Submit ...

  6. bzoj 1798: [Ahoi2009]Seq 维护序列seq 线段树 区间乘法区间加法 区间求和

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeO ...

  7. Bzoj 1798: [Ahoi2009]Seq 维护序列seq(线段树区间操作)

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec Memory Limit: 64 MB Description 老师交给小可可一个维护数列的任务,现在小可 ...

  8. BZOJ1798[Ahoi2009]Seq 维护序列seq 题解

    题目大意: 有长为N的数列,有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一段数全部加一个值; (3)询问数列中的一段数的和,由于答案可能很大,你只需输出这个数模P的值. ...

  9. 【bzoj1798】[Ahoi2009]Seq 维护序列seq 线段树

    题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一 ...

随机推荐

  1. mpvue重构小程序之坑点1

    对于最近刚做的项目,想着用框架重新架构一遍,方便以后拓展,毕竟现在拓展方向非常大. 目前主要碰到两个略坑的问题: 1: 关于用户授权信息的按钮,原生是以下方式,使用bindgetuserinfo事件 ...

  2. ES6初识-解构赋值

    数组解构赋值 [a,b]=[1,2]; . 方法返回 function f(){ return [1,2] } let a,b; [a,b]=f();//a=1,b=2   function f1() ...

  3. floyed dij spfa 模板

    /* SPFA模板 */ const int inf=0x3f3f3f3f; inline int SPFA(int s){ memset(dis,inf,sizeof(dis)); queue< ...

  4. Q&A - Nginx与Tomcat的区别?

    web上的server都叫web server,但是大家分工也有不同的. nginx常用做静态内容服务和代理服务器(不是你FQ那个代理),直面外来请求转发给后面的应用服务(tomcat,django什 ...

  5. 面向对象封装的web服务器

    import socket import re import os import sys # 由于前面太繁琐,可以用类封装一下,也可以分几个模块 class HttpServer(object): d ...

  6. DB设计工具——dbschema

      Preface       I've got a db design job about meeting room booking system last week.There're many s ...

  7. 带密匙的php加密解密示例分享

    <?phpheader("content-type:text/html;charset=utf-8");$id = "http://www.jb51.net&quo ...

  8. C语言数组篇(四)二维数组

      二维数组声明: ][] ={{,,},{,,}; //两行 三列         二维数组在声明的时候可以不写行,但一定要写列 ] = {{,},{,,},{}}; //未声明的地方自动补零 二维 ...

  9. 最小生成数kruskal算法和prim算法

    定义 连通图:在无向图中,若任意两个顶点vivi与vjvj都有路径相通,则称该无向图为连通图. 强连通图:在有向图中,若任意两个顶点vivi与vjvj都有路径相通,则称该有向图为强连通图. 连通网:在 ...

  10. python-5模块

    1-使用模块 import sys def test(): args = sys.argv if len(args)==1: print("hello word") elif le ...