「JSOI2014」序列维护
「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」序列维护的更多相关文章
- Loj #3059. 「HNOI2019」序列
Loj #3059. 「HNOI2019」序列 给定一个长度为 \(n\) 的序列 \(A_1, \ldots , A_n\),以及 \(m\) 个操作,每个操作将一个 \(A_i\) 修改为 \(k ...
- 「JSOI2014」矩形并
「JSOI2014」矩形并 传送门 我们首先考虑怎么算这个期望比较好. 我们不难发现每一个矩形要和 \(n - 1\) 个矩形去交,而总共又有 \(n\) 个矩形,所以我们把矩形两两之间的交全部加起来 ...
- 「HNOI2016」序列 解题报告
「HNOI2016」序列 有一些高妙的做法,懒得看 考虑莫队,考虑莫队咋移动区间 然后你在区间内部找一个最小值的位置,假设现在从右边加 最小值左边区间显然可以\(O(1)\),最小值右边的区间是断掉的 ...
- AC日记——「SDOI2017」序列计数 LibreOJ 2002
「SDOI2017」序列计数 思路: 矩阵快速幂: 代码: #include <bits/stdc++.h> using namespace std; #define mod 201704 ...
- loj #2051. 「HNOI2016」序列
#2051. 「HNOI2016」序列 题目描述 给定长度为 n nn 的序列:a1,a2,⋯,an a_1, a_2, \cdots , a_na1,a2,⋯,an,记为 a[1: ...
- 「JSOI2014」打兔子
「JSOI2014」打兔子 传送门 首先要特判 \(k \ge \lceil \frac{n}{2} \rceil\) 的情况,因为此时显然可以消灭所有的兔子,也就是再环上隔一个点打一枪. 但是我们又 ...
- 「JSOI2014」电信网络
「JSOI2014」电信网络 传送门 一个点选了就必须选若干个点,最大化点权之和,显然最大权闭合子图问题. 一个点向它范围内所有点连边,直接跑最大权闭合子图即可. 参考代码: #include < ...
- 「JSOI2014」学生选课
「JSOI2014」学生选课 传送门 看到这题首先可以二分. 考虑对于当前的 \(mid\) 如何 \(\text{check}\) 我们用 \(f_{i,j}\) 来表示 \(i\) 对 \(j\) ...
- 「JSOI2014」歌剧表演
「JSOI2014」歌剧表演 传送门 没想到吧我半夜切的 这道题应该算是 \(\text{JSOI2014}\) 里面比较简单的吧... 考虑用集合关系来表示分辨关系,具体地说就是我们把所有演员分成若 ...
随机推荐
- Html学习笔记(二)
Html头部 HTML <link>元素 <link> 标签定义了文档与外部资源之间的关系. <link> 标签通常用于链接到样式表: <head> & ...
- 8.10-Day2T1最小值
题目大意 裴蜀定理 题解 很简单... 我这个蒟蒻都猜的出来... 就求所有数的最大公约数 但注意 要加绝对值 因为gcd里面不能传负数 #include<cstdio> #inc ...
- bugku 你必须让他停下
首先打开链接会发现一个不断刷新的网页 然后使用抓包工具burpsuit抓网页 然后右键点击跳转到repeater 然后点击go一直点击 注意黄色区域的变化然后在点击过程中会发现flag 然后拿到答案
- Sql Server跨服务器操作数据
var serversSql = "select count(*) count from sys.servers WHERE name='ITSV'"; var result = ...
- C# 委托实例实现的多种类型
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- toString()和toLocaleString()方法有什么区别和联系
toString()和toLocaleString()有什么区别 偶然之间用到这两个方法 然后在数字转换成字符串的时候,并没有感觉这两个方法有什么区别,如下: 1 2 3 4 5 6 7 8 var ...
- 使用python同时替换json多个指定key的value
1.如何同时替换json多个指定key的value import json from jsonpath_ng import parse def join_paths(regx_path,new_val ...
- 在elementui表单中实现对vue-quill-editor富文本编辑器内容的绑定
1.v-model(表单标签双向绑定指令) v-model相当于:value=""和@input=""的结合 代码1: <input type=" ...
- linux配置放火墙开放端口
vi /etc/sysconfig/iptables -A INPUT -m state –state NEW -m tcp -p tcp –dport 80 -j ACCEPT(允许80端口通过防火 ...
- 1、安装GPIO Zero(Installing GPIO Zero)
学习目录:树莓派学习之路-GPIO Zero 官网地址:http://gpiozero.readthedocs.io/en/stable/installing.html 环境:UbuntuMeta-1 ...