「AHOI2014/JSOI2014」奇怪的计算器

传送门

我拿到这题首先是懵b的,因为感觉没有任何性质。。。

后来经过同机房dalao的指导发现可以把所有的 \(X\) 放到一起排序,然后我们可以发现每次操作都不会改变这个排完序之后的序列的单调性(始终单调不降),也就是说如果其中有一次操作使得数列中的某些数越界了,那么肯定是一个前缀或一个后缀,分别对应向下和向上越界。

然后我们就可以用线段树来搞,每次操作直接用线段树区间修改实现(具体细节待会讲),判断越界的话,我们就存一下区间的最小值和最大值,根据序列单调不降的性质,最小值就是区间左端点的值,最大值就是区间右端点的值,那么我们就可以在线段树上二分+区间赋值来实现批量处理越界的数。

那么接下来就讲一讲区间修改的一种巧妙实现方式:

其实很简单,我们把每次区间修改都写成 \(s_i \leftarrow s_i \times k_1 + a_i \times k_2 + k_3\) 的形式。

那么我们就可以通过调整参数 \(k_1, k_2, k_3\) 的值来很方便地实现区间加法、区间乘法、区间加上 \(a \times x\)、区间赋值的操作了。

参考代码:

#include <algorithm>
#include <cstdio>
#define rg register
#define int long long
#define file(x) freopen(x".in", "r", stdin), freopen(x".out", "w", stdout)
using namespace std;
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 _ = 1e5 + 5; int n, m, L, R, ans[_]; pair < int, int > a[_];
struct ask { int opt, x; } p[_];
struct node { int mn, mx, tag1, tag2, tag3; } 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].mn = t[lc(p)].mn, t[p].mx = t[rc(p)].mx; } inline void f(int p, int l, int r, int tag1, int tag2, int tag3) {
t[p].tag1 = t[p].tag1 * tag1;
t[p].tag2 = t[p].tag2 * tag1 + tag2;
t[p].tag3 = t[p].tag3 * tag1 + tag3;
t[p].mn = t[p].mn * tag1 + a[l].first * tag2 + tag3;
t[p].mx = t[p].mx * tag1 + a[r].first * tag2 + tag3;
} inline void pushdown(int p, int l, int r, int mid) {
f(lc(p), l, mid, t[p].tag1, t[p].tag2, t[p].tag3);
f(rc(p), mid + 1, r, t[p].tag1, t[p].tag2, t[p].tag3);
t[p].tag1 = 1, t[p].tag2 = t[p].tag3 = 0;
} inline void build(int p = 1, int l = 1, int r = m) {
t[p].tag1 = 1, t[p].tag2 = t[p].tag3 = 0;
if (l == r) { t[p].mn = t[p].mx = a[l].first; return ; }
int mid = (l + r) >> 1;
build(lc(p), l, mid), build(rc(p), mid + 1, r), pushup(p);
} inline void update_mn(int p = 1, int l = 1, int r = m) {
if (l == r) { f(p, l, r, 0, 0, L); return ; }
int mid = (l + r) >> 1;
pushdown(p, l, r, mid);
if (t[rc(p)].mn < L) f(lc(p), l, mid, 0, 0, L), update_mn(rc(p), mid + 1, r);
else update_mn(lc(p), l, mid);
pushup(p);
} inline void update_mx(int p = 1, int l = 1, int r = m) {
if (l == r) { f(p, l, r, 0, 0, R); return ; }
int mid = (l + r) >> 1;
pushdown(p, l, r, mid);
if (t[lc(p)].mx > R) f(rc(p), mid + 1, r, 0, 0, R), update_mx(lc(p), l, mid);
else update_mx(rc(p), mid + 1, r);
pushup(p);
} inline void query(int p = 1, int l = 1, int r = m) {
if (l == r) { ans[a[l].second] = t[p].mn; return ; }
int mid = (l + r) >> 1;
pushdown(p, l, r, mid);
query(lc(p), l, mid), query(rc(p), mid + 1, r);
} inline int cg(char c) {
if (c == '+') return 1; if (c == '-') return 2; if (c == '*') return 3; if (c == '@') return 4;
} signed main() {
#ifndef ONLINE_JUDGE
file("cpp");
#endif
read(n), read(L), read(R);
char s[5];
for (rg int x, i = 1; i <= n; ++i) scanf("%s", s), read(x), p[i] = (ask) { cg(s[0]), x };
read(m);
for (rg int x, i = 1; i <= m; ++i) read(x), a[i] = make_pair(x, i);
sort(a + 1, a + m + 1), build();
for (rg int i = 1; i <= n; ++i) {
if (p[i].opt == 1) f(1, 1, m, 1, 0, p[i].x);
if (p[i].opt == 2) f(1, 1, m, 1, 0, -p[i].x);
if (p[i].opt == 3) f(1, 1, m, p[i].x, 0, 0);
if (p[i].opt == 4) f(1, 1, m, 1, p[i].x, 0);
if (t[1].mn < L) update_mn();
if (t[1].mx > R) update_mx();
}
query();
for (rg int i = 1; i <= m; ++i) printf("%d\n", ans[i]);
return 0;
}

「AHOI2014/JSOI2014」奇怪的计算器的更多相关文章

  1. 「AHOI2014/JSOI2014」宅男计划

    「AHOI2014/JSOI2014」宅男计划 传送门 我们首先要发现一个性质:存货天数随买食物的次数的变化类似于单峰函数. 具体证明不会啊,好像是二分加三分来证明?但是没有找到明确的严格证明. 感性 ...

  2. 「AHOI2014/JSOI2014」拼图

    「AHOI2014/JSOI2014」拼图 传送门 看到 \(n \times m \le 10^5\) ,考虑根号分治. 对于 \(n < m\) 的情况,我们可以枚举最终矩形的上下边界 \( ...

  3. 「AHOI2014/JSOI2014」骑士游戏

    「AHOI2014/JSOI2014」骑士游戏 传送门 考虑 \(\text{DP}\). 设 \(dp_i\) 表示灭种(雾)一只编号为 \(i\) 的怪物的代价. 那么转移显然是: \[dp_i ...

  4. 「AHOI2014/JSOI2014」支线剧情

    「AHOI2014/JSOI2014」支线剧情 传送门 上下界网络流. 以 \(1\) 号节点为源点 \(s\) ,新建一个汇点 \(t\),如果 \(u\) 能到 \(v\),那么连边 \(u \t ...

  5. #3144. 「APIO 2019」奇怪装置

    #3144. 「APIO 2019」奇怪装置 题目描述 考古学家发现古代文明留下了一种奇怪的装置.该装置包含两个屏幕,分别显示两个整数 \(x\) 和 \(y\). 经过研究,科学家对该装置得出了一个 ...

  6. 「UNR#1」奇怪的线段树

    「UNR#1」奇怪的线段树 一道好题,感觉解法非常自然. 首先我们只需要考虑一次染色最下面被包含的那些区间,因为把无解判掉以后只要染了一个节点,它的祖先也一定被染了.然后发现一次染色最下面的那些区间一 ...

  7. 【LOJ #3144】「APIO 2019」奇怪装置

    题意: 定义将一个\(t\)如下转换成一个二元组: \[ f(t) = \begin{cases} x = (t + \left\lfloor \frac{t}{B} \right \rfloor) ...

  8. 「APIO 2019」奇怪装置

    题目 考虑推柿子 最开始的想法是如果两个\(t\)在\(mod\ B\)意义下相等,那么只需要比较一下\((t+\left \lfloor \frac{t}{B}\rfloor \right)mod\ ...

  9. BZOJ3878: [Ahoi2014&Jsoi2014]奇怪的计算器

    BZOJ3878: [Ahoi2014&Jsoi2014]奇怪的计算器 Description [故事背景] JYY有个奇怪的计算器,有一天这个计算器坏了,JYY希望你能帮助他写 一个程序来模 ...

随机推荐

  1. Docker - Deepin中docker不能启动容器,-d也无效

    问题重现 1. 搭建mysql docker run -p 3306:3306 --name docker-mysql-5.7 -v $PWD/conf:/etc/mysql/conf.d -v $P ...

  2. servlet中Request与response使用

    服务器根据请求自动创建传入HttpServletRequest对象和HttpServletResponse对象 @Override protected void service(HttpServlet ...

  3. DataGridView单元格显示密码

    DataGridView单元格显示密码 private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormatt ...

  4. CTF_论剑场 头像

    首先打开链接发现这个链接是一个头像 然后下载这个头像 通过hxd分析一下 在编辑中查找 flag 然后发现flag是一个用base64 加密的一串文字 然后我们将这串文字 解密 然后再通过md5 32 ...

  5. 吴裕雄 python 机器学习——数据预处理二元化Binarizer模型

    from sklearn.preprocessing import Binarizer #数据预处理二元化Binarizer模型 def test_Binarizer(): X=[[1,2,3,4,5 ...

  6. yum源文件

    yum源文件 2017年11月22日 11:59:36 cakincqm 阅读数 1052更多 分类专栏: Linux   版权声明:本文为博主原创文章,遵循CC 4.0 by-sa版权协议,转载请附 ...

  7. spark-shell中往mysql数据库写数据报错

    今天在看spark方面的知识的时候,在spark-shell中往mysql写数据时报错,错误信息如下: ERROR Executor: Exception in task 0.0 in stage 4 ...

  8. SpringMVC重定向(redirect)传参数,前端EL表达式接受值

    由于重定向相当于2次请求,所以无法把参数加在model中传过去.在上面例子中,页面获取不到msg参数.要想获取参数,可以手动拼url,把参数带在后面.Spring 3.1 提供了一个很好用的类:Red ...

  9. 学习laravel遇到的问题

    1.今天学习使用form的组件,首先使用composer命令来引入: composer require illuminate/html 接着在blog/config/app.php中的两个地方添加内容 ...

  10. php 发送手机验证码

    嗯哼,做为一个好的程序猿,一定要给顾客爸爸剁手的时候,充分的告诉他,你剁完手了,所以不只有邮件通知还要有手机短信的通知,今天就来写一下php发送验证码 1.首先我就写了几个个方法,因为配置在后台,直接 ...