「JSOI2014」序列维护

传送门

其实这题就是luogu的模板线段树2,之所以要发题解就是因为学到了一种比较NB的 \(\text{update}\) 的方式。(参见这题

我们可以把修改操作统一化,视为 \(ax + b\) 的形式,然后我们按照原来的套路来维护两个标记,分别代表 \(a\) 和 \(b\) ,那么我们的更新就可以这么写:

inline void f(int p, int atag, int mtag, int l, int r) {
t[p].sum = (t[p].sum * mtag % P + 1ll * atag * (r - l + 1) % P) % P;
t[p].atag = (t[p].atag * mtag + atag) % P;
t[p].mtag = t[p].mtag * mtag % P;
}

然后我们就只需要写一个维护 \(ax + b\) 操作的修改就可以了。

其实我们还可以发现这个东西还可以用于区间赋值 \((a = 0)\)。

简直很妙有没有

参考代码:

#include <cstdio>
#define rg register
#define file(x) freopen(x".in", "r", stdin), freopen(x".out", "w", stdout)
typedef long long LL;
template < class T > inline void read(T& s) {
s = 0; int f = 0; char c = getchar();
while ('0' > c || c > '9') f |= c == '-', c = getchar();
while ('0' <= c && c <= '9') s = s * 10 + c - 48, c = getchar();
s = f ? -s : s;
} const int _ = 100005; int n, m; LL P, a[_];
struct node { LL sum, atag, mtag; } t[_ << 2]; inline int lc(int p) { return p << 1; } inline int rc(int p) { return p << 1 | 1; } inline void pushup(int p) { t[p].sum = (t[lc(p)].sum + t[rc(p)].sum) % P; } inline void f(int p, int atag, int mtag, int l, int r) {
t[p].sum = (t[p].sum * mtag % P + 1ll * atag * (r - l + 1) % P) % P;
t[p].atag = (t[p].atag * mtag + atag) % P;
t[p].mtag = t[p].mtag * mtag % P;
} inline void pushdown(int p, int l, int r, int mid) {
if (t[p].atag != 0 || t[p].mtag != 1) {
f(lc(p), t[p].atag, t[p].mtag, l, mid);
f(rc(p), t[p].atag, t[p].mtag, mid + 1, r);
t[p].atag = 0, t[p].mtag = 1;
}
} inline void build(int p = 1, int l = 1, int r = n) {
t[p].atag = 0, t[p].mtag = 1;
if (l == r) { t[p].sum = a[l] % P; return ; }
int mid = (l + r) >> 1;
build(lc(p), l, mid), build(rc(p), mid + 1, r), pushup(p);
} inline void update(int ql, int qr, LL atag, LL mtag, int p = 1, int l = 1, int r = n) {
if (ql <= l && r <= qr) return f(p, atag, mtag, l, r);
int mid = (l + r) >> 1;
pushdown(p, l, r, mid);
if (ql <= mid) update(ql, qr, atag, mtag, lc(p), l, mid);
if (qr > mid) update(ql, qr, atag, mtag, rc(p), mid + 1, r);
pushup(p);
} inline LL query(int ql, int qr, int p = 1, int l = 1, int r = n) {
if (ql <= l && r <= qr) return t[p].sum;
int mid = (l + r) >> 1; LL res = 0;
pushdown(p, l, r, mid);
if (ql <= mid) res = (res + query(ql, qr, lc(p), l, mid)) % P;
if (qr > mid) res = (res + query(ql, qr, rc(p), mid + 1, r)) % P;
return res;
} int main() {
#ifndef ONLINE_JUDGE
file("cpp");
#endif
read(n), read(P);
for (rg int i = 1; i <= n; ++i) read(a[i]);
build();
read(m);
for (rg int opt, l, r; m--; ) {
read(opt); LL v;
if (opt == 3) read(l), read(r), printf("%lld\n", query(l, r));
else read(l), read(r), read(v), update(l, r, opt != 2 ? 0 : v, opt != 1 ? 1 : v);
}
return 0;
}

「JSOI2014」序列维护的更多相关文章

  1. Loj #3059. 「HNOI2019」序列

    Loj #3059. 「HNOI2019」序列 给定一个长度为 \(n\) 的序列 \(A_1, \ldots , A_n\),以及 \(m\) 个操作,每个操作将一个 \(A_i\) 修改为 \(k ...

  2. 「JSOI2014」矩形并

    「JSOI2014」矩形并 传送门 我们首先考虑怎么算这个期望比较好. 我们不难发现每一个矩形要和 \(n - 1\) 个矩形去交,而总共又有 \(n\) 个矩形,所以我们把矩形两两之间的交全部加起来 ...

  3. 「HNOI2016」序列 解题报告

    「HNOI2016」序列 有一些高妙的做法,懒得看 考虑莫队,考虑莫队咋移动区间 然后你在区间内部找一个最小值的位置,假设现在从右边加 最小值左边区间显然可以\(O(1)\),最小值右边的区间是断掉的 ...

  4. AC日记——「SDOI2017」序列计数 LibreOJ 2002

    「SDOI2017」序列计数 思路: 矩阵快速幂: 代码: #include <bits/stdc++.h> using namespace std; #define mod 201704 ...

  5. loj #2051. 「HNOI2016」序列

    #2051. 「HNOI2016」序列 题目描述 给定长度为 n nn 的序列:a1,a2,⋯,an a_1, a_2, \cdots , a_na​1​​,a​2​​,⋯,a​n​​,记为 a[1: ...

  6. 「JSOI2014」打兔子

    「JSOI2014」打兔子 传送门 首先要特判 \(k \ge \lceil \frac{n}{2} \rceil\) 的情况,因为此时显然可以消灭所有的兔子,也就是再环上隔一个点打一枪. 但是我们又 ...

  7. 「JSOI2014」电信网络

    「JSOI2014」电信网络 传送门 一个点选了就必须选若干个点,最大化点权之和,显然最大权闭合子图问题. 一个点向它范围内所有点连边,直接跑最大权闭合子图即可. 参考代码: #include < ...

  8. 「JSOI2014」学生选课

    「JSOI2014」学生选课 传送门 看到这题首先可以二分. 考虑对于当前的 \(mid\) 如何 \(\text{check}\) 我们用 \(f_{i,j}\) 来表示 \(i\) 对 \(j\) ...

  9. 「JSOI2014」歌剧表演

    「JSOI2014」歌剧表演 传送门 没想到吧我半夜切的 这道题应该算是 \(\text{JSOI2014}\) 里面比较简单的吧... 考虑用集合关系来表示分辨关系,具体地说就是我们把所有演员分成若 ...

随机推荐

  1. app项目中遇到TCP分包,H5端对分包进行拼包

    之前有个需求,由于H5端不支持TCPSocket通信,于是中间搭了个安卓框架作为通信的介质,在开发中遇到一个问题,当后端传一个比较大的数据上来时,一条完整的数据会没有规矩的分成若干个包,每条数据可能不 ...

  2. 1.BMap(百度地图)第二次加载显示不全

    问题: bmap第一次加载显示没问题: 第二次 再次加载这个页面时,地图的显示出现了问题: . 分析问题出现原因:你要确保dom创建后且处于显示状态(即display不能为none)才能再次初始化地图 ...

  3. nginx的负载均衡配置

    1.下载nginx的压缩包,可以去官网下载 2.解压缩,可以看到其中有个conf的文件夹,在该目录中,nginx.conf配置文件就是核心配置文件 3.默认配置 #user nobody; worke ...

  4. 一个超几何函数$_3F_2$的积分

    \[\Large\displaystyle \int_0^\infty{_3F_2}\left(\begin{array}c\dfrac58,\dfrac58,\dfrac98\\\dfrac12,\ ...

  5. Win2012或Win2016安装网卡

    在电脑安装了Windows Server 2012或者2016等系统之后,可能面临的很大的问题就是没有有线或无线网卡. 1.安装网卡的功能 2.一直到“功能”这部分,选择安装“DirectPlay”和 ...

  6. 获取表格数据转换为JSON字符串

    核心代码JavaScript代码: 方法一 function sc () { var myTable=document.getElementById("myTable"); //获 ...

  7. 全局下的isFinite

     isFinite() 函数用于检查其参数是否是无穷大 1. 他是一个全局对象,可以在js代码中直接使用 2. isFinite() 函数用于检查其参数是否是无穷大. 3. 如果 number 是有限 ...

  8. P1030 求先序排列 (一个非常棒的写法)

    理论正确就是真正的正确,误... 就是找嘛,找到每一个对应字符,然后对应的左右子树的区间,然后就可以了. #include <bits/stdc++.h> using namespace ...

  9. 机器学习 — 从mnist数据集谈起

    做了一些简单机器学习任务后,发现必须要对数据集有足够的了解才能动手做一些事,这是无法避免的,否则可能连在干嘛都不知道,而一些官方例程并不会对数据集做过多解释,你甚至连它长什么样都不知道... 以skl ...

  10. P1579

    AC: #include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for(int i = a; i < b ...