首页 > 其他分享 >【Ynoi2018】天降之物

【Ynoi2018】天降之物

时间:2023-09-24 18:55:49浏览次数:48  
标签:Ynoi2018 int32 return bl 之物 ins a1 a2 天降

【Ynoi2018】天降之物

题意

给定一个长为 \(n\) 的序列 \(a\),支持两种操作:

  1. 将所有 \(a_p = x\) 修改为 \(y\)。

  2. 查询 \(\min(|i-j|)\),满足 \(a_i = x \and a_j = y\) 或者 \(a_i = y \and a_j = x\)。

题解

考虑序列分块,首先考虑块内贡献,设块长为 \(B\),由于分块的 \(B\) 一般为根号级别,直接将一个块内数离散化,预处理一个数在块内出现的第一个位置和最后一个位置,记录 \(ins_{i,j}\) 表示 \((i, j)\) 的答案。

预处理是 \(O(\frac{n}{B}(B^2 + B\log B))\) 的复杂度。

接着先思考询问,一个块内的处理完了,直接查,如果不在一个块,一定是前一个在块最后,后一个在块开头。前面处理的直接用上,注意答案不一定在相邻的两个块内(卡了很久)。

然后是修改,分类讨论一下

  1. 如果 \(x\) 没出现,直接跳过。
  2. 如果 \(y\) 没出现,显然总颜色数不变,直接让 \(y\) 继承 \(x\) 的信息即可。
  3. 如果 \(x\) 和 \(y\) 都出现,对于 \(ins\) 我们重新遍历一遍块更新答案即可。另外东西直接取 \(\min\) 或者 \(max\) 即可。由于每次修改会让一个块少一个颜色,所以总复杂度是 \(O(n\sqrt n)\) 的。

注意修改完要把 \(x\) 在这个块内标记为不存在。

注意一点细节卡个常就过了。

#include <bits/stdc++.h>
namespace FileHeader {
  using int16 = int16_t;
  using int32 = int32_t;
  using int64 = int64_t;
  using uint32 = uint32_t;
  using uint64 = uint64_t;
  #define ep emplace
  #define eb emplace_back
  #define all(x) x.begin(), x.end()
  FILE* fin, * fout, * ferr;
  int32 read() {
    int32 t = 0, f = 0;
    char ch = fgetc(fin);
    for (; !isdigit(ch); ch = fgetc(fin)) f ^= (ch == '-');
    for (; isdigit(ch); ch = fgetc(fin)) t = (t << 1) + (t << 3) + (ch ^ 48);
    return f ? -t : t;
  }
  class Iterator {
    public:
      Iterator(int32 _val = 0): _val(_val) {}
      bool operator !=(const Iterator &other) const { return this->_val != other._val; }
      int32 operator *() { return this->_val; }
      int32 operator ++() { return ++this->_val; }
    private:
      int32 _val;
  };
  class Range {
    public:
      Range(int32 _l = 0, int32 _r = 0): _begin(_l), _end(_r + 1) {}
      Iterator begin() { return Iterator(this->_begin); }
      Iterator end() { return Iterator(this->_end); }
    private:
      int32 _begin, _end;
  };
}
using namespace FileHeader;
namespace Solution_Of_P5397 {
  static const int32 N = 100010, B = 255, M = N / B + 10;
  static const int32 inf32 = 0x3f3f3f3f;
  int32 n, m, bl;
  int32 a[N], b[N];
  int32 L[M], R[M], len[M];
  int16 ins[N][M];
  int16 inp[N][M];
  int32 fir[N], sec[N];
  template<typename T>
  inline void cmin(T &x, T y) { return x = (x < y ? x : y), void(); }
  template<typename T>
  inline void cmax(T &x, T y) { return x = (x > y ? x : y), void(); }
  inline void init(int32 bl, int32 l, int32 r) {
    L[bl] = l, R[bl] = r;
    int32 P = R[bl - 1];
    std::vector<int32> numric;
    for (auto i : Range(l, r)) numric.eb(a[i]);
    std::sort(all(numric), [&](int32 a, int32 b) { return a < b; });
    numric.erase(std::unique(all(numric)), numric.end());
    len[bl] = static_cast<int32>(numric.size());
    for (int32 i = l; i <= r; ++i) {
      b[i] = std::lower_bound(all(numric), a[i]) - numric.begin() + 1;
      inp[a[i]][bl] = b[i];
    }
    for (int32 i = r; i >= l; --i) fir[P + b[i]] = i;
    for (int32 i = l; i <= r; ++i) sec[P + b[i]] = i;
    for (int32 i = 1; i <= len[bl]; ++i)
      std::memset(ins[P + i], 64, (len[bl] + 1) << 1);
    for (auto i : Range(l, r))
      for (auto j : Range(i + 1, r)) {
        int32 a1 = inp[a[i]][bl], a2 = inp[a[j]][bl];
        if (a1 > a2) std::swap(a1, a2);
        cmin(ins[P + a1][a2], int16(j - i));
      }
    return void();
  }
  inline int32 trans(int16 x) {
    if (x == 0x3f3f) return 0x3f3f3f3f;
    return static_cast<int32>(x);
  }
  inline int32 query(int32 x, int32 y) {
    if (x == y) {
      for (auto i : Range(1, bl))
        if (inp[x][i]) return 0;
      return 0x3f3f3f3f;
    }
    int32 ans = inf32;
    int32 lst1 = -inf32, lst2 = -inf32;
    for (auto i : Range(1, bl)) {
      int16 a1 = inp[x][i], a2 = inp[y][i];
      int32 P = R[i - 1];
      if (a1) cmin(ans, fir[P + a1] - lst2);
      if (a2) cmin(ans, fir[P + a2] - lst1);
      if (a1) lst1 = sec[P + a1];
      if (a2) lst2 = sec[P + a2];
      if (a1 > a2) std::swap(a1, a2);
      if (a1 && a2) cmin(ans, trans(ins[P + a1][a2]));
    }
    return ans;
  }
  inline void modify1(int32 bl, int32 x, int32 y) {
    inp[y][bl] = inp[x][bl];
    inp[x][bl] = 0;
    return void();
  }
  inline void modify2(int32 bl, int32 x, int32 y) {
    int16 a1 = inp[x][bl], a2 = inp[y][bl];
    int32 P = R[bl - 1];
    cmin(fir[P + a2], fir[P + a1]);
    cmax(sec[P + a2], sec[P + a1]);
    fir[P + a1] = sec[P + a1] = 0;
    if (a1 < a2) {
      for (auto i : Range(1, a1)) cmin(ins[P + i][a2], ins[P + i][a1]);
      for (auto i : Range(a1 + 1, a2)) cmin(ins[P + i][a2], ins[P + a1][i]);
      for (auto i : Range(a2 + 1, len[bl])) cmin(ins[P + a2][i], ins[P + a1][i]);
    } else {
      for (auto i : Range(1, a2)) cmin(ins[P + i][a2], ins[P + i][a1]);
      for (auto i : Range(a2 + 1, a1)) cmin(ins[P + a2][i], ins[P + i][a1]);
      for (auto i : Range(a1 + 1, len[bl])) cmin(ins[P + a2][i], ins[P + a1][i]);
    }
    inp[x][bl] = 0;
    return void();
  }
  inline void modify(int32 x, int32 y) {
    if (x == y) return void();
    for (auto i : Range(1, bl)) {
      if (!inp[x][i]) continue;
      if (!inp[y][i]) modify1(i, x, y);
      else modify2(i, x, y);  
    }
    return void();
  }
  inline void main() {
    fin = stdin, fout = stdout, ferr = stderr;
    // fin = fopen("data.in", "r");
    // fout = fopen("data.out", "w");
    n = read(), m = read();
    for (auto i : Range(1, n)) a[i] = read();
    bl = (n - 1) / B + 1;
    for (auto i : Range(1, bl)) init(i, (i - 1) * B + 1, std::min(n, i * B));
    for (auto t : Range(1, m)) {
      static int32 op, x, y, lastans = 0;
      op = read(), x = read() ^ lastans, y = read() ^ lastans; 
      if (op == 1) modify(x, y);
      if (op == 2) {
        lastans = query(x, y);    
        if (lastans == inf32) lastans = 0, fputs("Ikaros\n", fout);
        else fprintf(fout, "%d\n", lastans);
      }  
    }
    return void();
  }
}
signed main() { return Solution_Of_P5397::main(), 0; }

标签:Ynoi2018,int32,return,bl,之物,ins,a1,a2,天降
From: https://www.cnblogs.com/Maraschino/p/17726422.html

相关文章

  • 消失之物
    P4141消失之物是一种被称为退背包的背包。我们先求出不删除任何一个数的答案,这就是一个经典的背包问题,可以使用空间优化。然后,我们考虑删除一个数。我们有一个重要的性质:物品的顺序与方案数无关,如\(1,2,3\),\(2,1,3\)没有区别。于是,我们可以将要删除的这个数看作刚刚插入。......
  • 「突刺贯穿第二分块」P4117 [Ynoi2018] 五彩斑斓的世界
    很帅气!分块在线转离线,考虑每个块对于询问的贡献。维护块的max和tag分别代表最大值和减了多少。先考虑整块,\(max<2*x:\)每次暴力区间平移即可。否则对于\([1,x]\)全部加上\(x\)平移到\([x+1,x*2]\),然后区间整体减\(x\)即可。散块怎么做?暴力减,然后重构块......
  • 初识CAN总线之物理层
    一、CAN简介CAN:ControllerAreaNetwork,控制局域网络,最早由德国BOSCH(博世)开发,,目前已经是国际标准(ISO11898),是当前应用最广泛的现场总线之一。CAN总线主要用于汽车的检测和控制,目的为适应汽车的“减少线束的数量”、“通过多个网络进行大量数据的高速传输”的需求。BOSCH......
  • ThingsKit物联网平台产品管理之物模型
    概述物模型是ThingsKit物联网平台为产品定义的数据模型,用于描述产品的功能。本文介绍物模型相关概念和使用限制。功能说明物模型是物理空间中的实体(如传感器、车载装置、楼宇、工厂等)在云端的数字化表示,从属性、服务和事件三个维度,分别描述了该实体是什么、能做什么、可以对外......
  • 发生的不存在之物
    近日。没有眼泪的毕业。没有神采的故友。没有陪伴的饭局。没有胆怯的密室。没有期待的暑假。没有声音的游戏。......
  • CF896E/洛谷 P4117 [Ynoi2018]五彩斑斓的世界/Welcome home, Chtholly
    分块。我们先来考虑修改对整块的影响。记值域为\(V=10^5\)。考虑对每一块维护\(V\)个集合\(S_1,S_2,\cdots,S_V\),第\(i\)个集合\(S_i\)维护了区间中所有\(=i\)的元素的一些信息,并维护区间的最大值\(m\),对于一次操作\(x\):若\(m\le2x\),我们暴力对每个\(i\in[x+1,......
  • threejs-css2dObject操作之物体遮挡标签后应该隐藏,而不是出现透视效果
    先看coding之前的效果: 这些在背面的标签的,转到一定角度,被模型遮挡后,理论上就不应该被看到。这才是比较符合实际的coding之后(另一侧对称点就被隐藏): 具体代码(j借助于光线投影)://绑定鼠标事件,当用户移动视角后触发()functionbindRayShotEvent(){document.addEvent......
  • iOS MachineLearning 系列(4)—— 静态图像分析之物体识别与分类
    iOSMachineLearning系列(4)——静态图像分析之物体识别与分类本系列的前几篇文件,详细了介绍了Vision框架中关于静态图片区域识别的内容。本篇文章,我们将着重介绍静态图片中物体的识别与分类。物体识别和分类也是MachineLearning领域重要的应用。通过大量的图片数据进行训练后,模型......
  • openGauss之物理备份与恢复实践操作(openGauss课程openGauss3.0.0)
    一、opengauss的背景和行业现状 2022年,七大openGauss商业版发布,是基于openGauss3.0推出商业发行版目前海量数据库Vastbase表现最佳,一直是TOP1作者认为之所以海量数据库Vastbase目前无法被同行超越,和各家研发实力和技术背景有关 众所周知,opengauss起源于postgresql,在此基......
  • iOS MachineLearning 系列(4)—— 静态图像分析之物体识别与分类
    iOSMachineLearning系列(4)——静态图像分析之物体识别与分类本系列的前几篇文件,详细了介绍了Vision框架中关于静态图片区域识别的内容。本篇文章,我们将着重介绍静态图片中物体的识别与分类。物体识别和分类也是MachineLearning领域重要的应用。通过大量的图片数据进行训练后,模......