洛谷P2023 [AHOI2009]维护序列

区间修改

当我们要修改一个区间时,要保证 \(ax+b\) 的形式,即先乘后加的形式。当将区间乘以一个数 \(k\) 时,原来的区间和为 \(ax+b\) ,乘以 \(k\) 得 \(k(ax+b)=kax+kb\) 。

区间加一个数更加简单,原来的区间和为 \(ax+b\) ,加上一个 \(k\) 为 \(ax+b+k\) ,合并 \(b\) ,\(k\) 得 \(ax+(b+k)\) 。

标记下传

\[a(a'x+b')+b = (aa')\cdot x + (ab'+b)
\]

#include<bits/stdc++.h>

using namespace std;
#define lson l, mid, root << 1
#define rson mid + 1, r, root << 1 | 1 const int maxn = 100005;
long long tree[maxn << 2];
int n, p, q;
struct L{
long long mul, add;
}label[maxn << 2]; inline void pushUp(int root)
{
tree[root] = (tree[root << 1] + tree[root << 1 | 1]) % p;
}
inline void pushDown(int root, int len)
{
if(label[root].add == 0 && label[root].mul == 1) return;
else{
tree[root << 1] = (label[root].mul * tree[root << 1] + label[root].add * (len - (len >> 1))) % p;/***长度划分***/
tree[root << 1 | 1] = (label[root].mul * tree[root << 1 | 1] + label[root].add * (len >> 1)) % p;
label[root << 1].add = (label[root].mul * label[root << 1].add + label[root].add) % p;
label[root << 1 | 1].add = (label[root].mul * label[root << 1 | 1].add + label[root].add) % p;
label[root << 1].mul = (label[root << 1].mul * label[root].mul) % p;
label[root << 1 | 1].mul = (label[root << 1 | 1].mul * label[root].mul) % p;
label[root].add = 0; label[root].mul = 1;
}
}
void build(int l, int r, int root)
{
label[root].add = 0; label[root].mul = 1;
if(l == r){
scanf("%lld", &tree[root]); return;
}
int mid = (l + r) >> 1;
build(lson); build(rson);
pushUp(root);
}
void update(int l, int r, int root, int L, int R, int tag, int c)
{
if(L == l && R == r){
if(tag == 1){
tree[root] = tree[root] * c % p;
label[root].add = label[root].add * c % p;
label[root].mul = label[root].mul * c % p;
}else{
tree[root] = (tree[root] + c * (r - l + 1)) % p;
label[root].add = (label[root].add + c) % p;
}
return;
}
pushDown(root, r - l + 1);
int mid = (l + r) >> 1;
if(L >= mid + 1) update(rson, L, R, tag, c);
else if(R <= mid) update(lson, L, R, tag, c);
else{
update(lson, L, mid, tag, c); update(rson, mid + 1, R, tag, c);
}
pushUp(root);
}
long long query(int l, int r, int root, int L, int R)
{
if(L == l && R == r){
return tree[root] % p;
}
pushDown(root, r - l + 1);
int mid = (l + r) >> 1;
if(L >= mid + 1) return (query(rson, L, R) % p);
else if(R <= mid) return (query(lson, L, R) % p);
else{
return ((query(lson, L, mid) + query(rson, mid + 1, R)) % p);
}
}
int main()
{
scanf("%d%d", &n, &p);
build(1, n, 1);
scanf("%d", &q);
for(int cas = 1; cas <= q; cas++){
int tag, t, g, c;
scanf("%d", &tag);
if(tag == 1){
scanf("%d%d%d", &t, &g, &c);
update(1, n, 1, t, g, 1, c);
}
else if(tag == 2){
scanf("%d%d%d", &t, &g, &c);
update(1, n, 1, t, g, 2, c);
}
else{
scanf("%d%d", &t, &g);
printf("%lld\n", query(1, n, 1, t, g) % p);
}
}
return 0;
}

洛谷P2023 [AHOI2009]维护序列(线段树区间更新,区间查询)的更多相关文章

  1. 洛谷 P2023 [AHOI2009]维护序列 || 线段树加法和乘法运算

    原理倒是非常简单.设原数为x,加法的lazytag为b,乘法的lazytag为a,操作数为c,那么原式为ax+b,乘上c后(ax+b)c=(ac)*x+b*c,加上c后(ax+b)+c=ax+(b+c ...

  2. 洛谷 P2023 [AHOI2009]维护序列 题解

    P2023 [AHOI2009]维护序列 题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,-,aN .有如下三种操作形式: (1)把数列中 ...

  3. 洛谷 P2023 [AHOI2009]维护序列

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

  4. 【题解】洛谷P2023 [AHOI2009] 维护序列(线段树)

    洛谷P2023:https://www.luogu.org/problemnew/show/P2023 思路 需要2个Lazy-Tag 一个表示加的 一个表示乘的 需要先计算乘法 再计算加法 来自你谷 ...

  5. [洛谷P2023] [AHOI2009]维护序列

    洛谷题目链接:[AHOI2009]维护序列 题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,-,aN .有如下三种操作形式: (1)把数列 ...

  6. [P2023][AHOI2009]维护序列(线段树)

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

  7. 洛谷 2023 [AHOI2009]维护序列

    洛谷 2023 [AHOI2009]维护序列 洛谷原题传送门 这个题也是一道经典的线段树模版(其实洛谷的模版二改一下输入顺序就能AC),其中包括区间乘法修改.区间加法修改.区间查询三个操作. 线段树的 ...

  8. POJ.2528 Mayor's posters (线段树 区间更新 区间查询 离散化)

    POJ.2528 Mayor's posters (线段树 区间更新 区间查询 离散化) 题意分析 贴海报,新的海报能覆盖在旧的海报上面,最后贴完了,求问能看见几张海报. 最多有10000张海报,海报 ...

  9. POJ.3468 A Simple Problem with Integers(线段树 区间更新 区间查询)

    POJ.3468 A Simple Problem with Integers(线段树 区间更新 区间查询) 题意分析 注意一下懒惰标记,数据部分和更新时的数字都要是long long ,别的没什么大 ...

随机推荐

  1. Java Web开发技术教程入门-初识动态网页

    这段时间学校搞了一个"阅战阅勇"的阅读活动,奖品还是挺丰富的~于是,奔着这些奖品,我去图书馆借了这本<Java Web开发技术教程>.一是为了那些丰富的奖品,二是为了回 ...

  2. Linux端口是否占用的方法

    1.netstat或ss命令 netstat -anlp | grep 80 2.lsof命令 这个命令是查看进程占用哪些文件的 lsof -i:80 3.fuser命令 fuser命令和lsof正好 ...

  3. 邀请好友注册页面光标点到输入框后,输入框会先灰一下。只有ios存在

    输入框会先灰一下.只有ios存在 用这一行代码可以解决问题: -webkit-tap-highlight-color:transparent;

  4. Linux设置远程免密登录

    1.生成公钥 / 私钥对 [root@localhost ~]# ssh-keygen -t rsa -P '' -P表示密码,-P '' 就表示空密码,也可以不用-P参数,这样就要三车回车,用-P就 ...

  5. 10.css3动画--过渡动画--trasition

    Transition简写属性. Transition-property规定应用过渡的css属性的名称. . Transition-timing-function过渡效果的时间曲线,默认是ease. L ...

  6. 关于 i++ 和 ++ i

    先看一下代码,猜想一下输出值 @Testpublic void test() { int i =1; int a,b=0; i++; a=(i++); System.out.println(a); S ...

  7. linux的安全--Selinux,tcp_wrappers,iptables使用

    一.linux安全 安全主要是端口与服务的对应配置 1.1 linux安全主要通过下面三个进行加固 Selinux----主要是对内核的访问权限加以控制 tcp_wrappers---一定程度上限制某 ...

  8. Laravel session的保存机制

    与$_SESSION不同Laraver中的session是在当次程序执行完毕时保存到文件或其他存储引擎中的,也就是说如果使用了die等强制结束程序的函数将不会自动保存session导致session失 ...

  9. puppet工简介一

    puppet简介一 puppet工作原理 puppet 是一个配置管理工具, 典型的, puppet 是一个 C/S 结构, 当然,这里的 C 可以有很多,因 此,也可以说是一个星型结构. 所有的 p ...

  10. Github删除仓库文件夹问题集合

    记得上次使用GitHub,看时间提示,最近的一次,是三年前,而且都是长传文件,这次是删除文件,才发现删除库可以,但是删除库里的某个目录,就不行了,除非是下载下来,在GitHub把仓库删了重新添加.使用 ...