「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\)、区间赋值的操作了。

参考代码:

  1. #include <algorithm>
  2. #include <cstdio>
  3. #define rg register
  4. #define int long long
  5. #define file(x) freopen(x".in", "r", stdin), freopen(x".out", "w", stdout)
  6. using namespace std;
  7. template < class T > inline void read(T& s) {
  8. s = 0; int f = 0; char c = getchar();
  9. while ('0' > c || c > '9') f |= c == '-', c = getchar();
  10. while ('0' <= c && c <= '9') s = s * 10 + c - 48, c = getchar();
  11. s = f ? -s : s;
  12. }
  13. const int _ = 1e5 + 5;
  14. int n, m, L, R, ans[_]; pair < int, int > a[_];
  15. struct ask { int opt, x; } p[_];
  16. struct node { int mn, mx, tag1, tag2, tag3; } t[_ << 2];
  17. inline int lc(int p) { return p << 1; }
  18. inline int rc(int p) { return p << 1 | 1; }
  19. inline void pushup(int p) { t[p].mn = t[lc(p)].mn, t[p].mx = t[rc(p)].mx; }
  20. inline void f(int p, int l, int r, int tag1, int tag2, int tag3) {
  21. t[p].tag1 = t[p].tag1 * tag1;
  22. t[p].tag2 = t[p].tag2 * tag1 + tag2;
  23. t[p].tag3 = t[p].tag3 * tag1 + tag3;
  24. t[p].mn = t[p].mn * tag1 + a[l].first * tag2 + tag3;
  25. t[p].mx = t[p].mx * tag1 + a[r].first * tag2 + tag3;
  26. }
  27. inline void pushdown(int p, int l, int r, int mid) {
  28. f(lc(p), l, mid, t[p].tag1, t[p].tag2, t[p].tag3);
  29. f(rc(p), mid + 1, r, t[p].tag1, t[p].tag2, t[p].tag3);
  30. t[p].tag1 = 1, t[p].tag2 = t[p].tag3 = 0;
  31. }
  32. inline void build(int p = 1, int l = 1, int r = m) {
  33. t[p].tag1 = 1, t[p].tag2 = t[p].tag3 = 0;
  34. if (l == r) { t[p].mn = t[p].mx = a[l].first; return ; }
  35. int mid = (l + r) >> 1;
  36. build(lc(p), l, mid), build(rc(p), mid + 1, r), pushup(p);
  37. }
  38. inline void update_mn(int p = 1, int l = 1, int r = m) {
  39. if (l == r) { f(p, l, r, 0, 0, L); return ; }
  40. int mid = (l + r) >> 1;
  41. pushdown(p, l, r, mid);
  42. if (t[rc(p)].mn < L) f(lc(p), l, mid, 0, 0, L), update_mn(rc(p), mid + 1, r);
  43. else update_mn(lc(p), l, mid);
  44. pushup(p);
  45. }
  46. inline void update_mx(int p = 1, int l = 1, int r = m) {
  47. if (l == r) { f(p, l, r, 0, 0, R); return ; }
  48. int mid = (l + r) >> 1;
  49. pushdown(p, l, r, mid);
  50. if (t[lc(p)].mx > R) f(rc(p), mid + 1, r, 0, 0, R), update_mx(lc(p), l, mid);
  51. else update_mx(rc(p), mid + 1, r);
  52. pushup(p);
  53. }
  54. inline void query(int p = 1, int l = 1, int r = m) {
  55. if (l == r) { ans[a[l].second] = t[p].mn; return ; }
  56. int mid = (l + r) >> 1;
  57. pushdown(p, l, r, mid);
  58. query(lc(p), l, mid), query(rc(p), mid + 1, r);
  59. }
  60. inline int cg(char c) {
  61. if (c == '+') return 1; if (c == '-') return 2; if (c == '*') return 3; if (c == '@') return 4;
  62. }
  63. signed main() {
  64. #ifndef ONLINE_JUDGE
  65. file("cpp");
  66. #endif
  67. read(n), read(L), read(R);
  68. char s[5];
  69. for (rg int x, i = 1; i <= n; ++i) scanf("%s", s), read(x), p[i] = (ask) { cg(s[0]), x };
  70. read(m);
  71. for (rg int x, i = 1; i <= m; ++i) read(x), a[i] = make_pair(x, i);
  72. sort(a + 1, a + m + 1), build();
  73. for (rg int i = 1; i <= n; ++i) {
  74. if (p[i].opt == 1) f(1, 1, m, 1, 0, p[i].x);
  75. if (p[i].opt == 2) f(1, 1, m, 1, 0, -p[i].x);
  76. if (p[i].opt == 3) f(1, 1, m, p[i].x, 0, 0);
  77. if (p[i].opt == 4) f(1, 1, m, 1, p[i].x, 0);
  78. if (t[1].mn < L) update_mn();
  79. if (t[1].mx > R) update_mx();
  80. }
  81. query();
  82. for (rg int i = 1; i <= m; ++i) printf("%d\n", ans[i]);
  83. return 0;
  84. }

「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. ubuntu刪除軟件

    1.打开一个终端,输入dpkg --list ,按下Enter键,终端输出以下内容,显示的是你电脑上安装的所有软件2.在终端中找到你需要卸载的软件的名称,列表是按照首字母排序的.3.在终端上输入命令s ...

  2. 1012 The Best Rank

    1012 The Best Rank 1. 注意点 一名同学同样排名下的科目优先级问题 不同同学分数相同时排名相同,注意 排名不是 1 1 2 3 4 这种, 而是 1 1 3 4 5 注意到有些同学 ...

  3. [蓝桥杯][基础训练]FJ的字符串

    Description FJ在沙盘上写了这样一些字符串: A1 = “A” A2 = “ABA” A3 = “ABACABA” A4 = “ABACABADABACABA” … … 你能找出其中的规律 ...

  4. python的logging库

    logging库 简介 logging库提供日志打印功能. 值得一提的是,不仅能打印到日志文件,还能打印到控制台. 日志级别 logging一共分为5个级别,从低到高依次为:  DEBUG<IN ...

  5. [Fiddler学习] - Mock的简单实现原理及方法

    最近在研究Fidder抓包并做一点测试工作,下面介绍一下Fiddler的实现原理: 简单来说从clent,server端发出来的请求,都需要通过Fiddler进行代理走一遍.如果有任何请求需要做修改, ...

  6. stopWatch 用法

    package com.example.stopwatch; import org.springframework.util.StopWatch; public class TestStopWatch ...

  7. KafKa集群安装、配置

    一.事前准备 1.kafka官网:http://kafka.apache.org/downloads. 2.选择使用版本下载. 3.kafka集群环境准备:(linux) 192.168.145.12 ...

  8. Spring IoC(一)bean实例化和依赖注入

    1.IoC容器概述 IoC 全称为 Inversion of Control,翻译为 “控制反转”,它还有一个别名为 DI(Dependency Injection),即依赖注入. 所谓 IOC ,就 ...

  9. netty(五) channel

    问题 channel 是如何处理发送一半中断后继续重发的 channel 具体作用是什么 概述 这一节我们将介绍 Channel 和内部接口 Unsafe .其中Unsafe 是内部接口,聚合在Cha ...

  10. 【译】高级T-SQL进阶系列 (四)【上篇】:使用游标进行行级别处理

    [译注:此文为翻译,由于本人水平所限,疏漏在所难免,欢迎探讨指正] 原文链接:传送门. 正常来说,使用游标并不是处理记录集的最佳方式.然而当一个经验丰富的程序员第一次开始写TSQL时,他们经常会寻找其 ...