首页 > 其他分享 >CF1707E Replace

CF1707E Replace

时间:2023-02-03 08:33:04浏览次数:41  
标签:10 ch const int Replace CF1707E itv inline

CF1707E Replace

完全没想到从这种角度考虑性质。

一开始的思路是把每种区间表示为一个节点建树,然后答案就是深度,但是很显然节点数是平方级别的,所以就寄了。尝试使用数据结构维护,但是做不到,很伤心。

看一眼题解,有一个神仙性质 \(f(l,r) = \bigcup_{i=l}^{r-1} f(i,i+1)\)。

这个怎么证明呢,考虑区间的最大值和最小值,中间的部分都可以被覆盖,所以就是对的。

那么可以归纳出一个更强的结论 \(f^k(l,r) = \bigcup_{i=l}^{r-1} f^k(i,i+1)\)。

证明和上面类似。那么就有了一个很优美的方式表示 \(f^k(l,r)\)。

现在想要知道最小的 \(k\) 使得 \(f^k(l,r) = (1,n)\),直接倍增就可以了。

这个故事告诉我们:处理关于区间的操作时可以考虑大区间和小区间之间的关系,进而在处理询问时将小区间组合为大区间维护信息。

#include <cstdio>
#include <iostream>

using namespace std;

namespace IO {
  #define isdigit(x) (x >= '0' && x <= '9')
  template<typename T>
  inline void read(T &x) {
    x = 0; char ch = getchar(); int f = 0;
    for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
    for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - '0';
    if(f) x = -x;
  }
  template<typename T>
  inline void write(T x) {
    if(x < 0) putchar('-'), x = -x;
    if(x > 9) write(x / 10);
    putchar(x % 10 + '0');
  }
  #undef isdigit
}
using namespace IO;

const int N = 2e5 + 10;
const int P = 20;
int n, q;
int a[N];
int lg[N];

struct itv {
  int l, r;
  inline itv operator + (itv a) const{
    a.l = min(a.l, l), a.r = max(a.r, r);
    return a;
  }
  inline bool operator == (itv a) const{
    return l == a.l && r == a.r;
  }
}t[N][P][P];

inline itv query(itv x, int p) {
  int l = x.l, r = x.r;
  int q = lg[r - l + 1];
  return t[l][q][p] + t[r - (1 << q) + 1][q][p];
}

int main() {
  read(n), read(q);
  for(int i = 1; i <= n; ++i)
    read(a[i]);
  for(int i = 2; i <= n; ++i)
    lg[i] = lg[i >> 1] + 1;
  for(int i = 1; i <= n; ++i) 
    t[i][0][0] = (itv){a[i], a[i]};
  for(int i = 1; i < P; ++i)
    for(int j = 1; j <= n - (1 << i) + 1; ++j)
      t[j][i][0] = t[j][i - 1][0] + t[j + (1 << (i - 1))][i - 1][0];
  for(int j = 1; j < P; ++j)
    for(int i = 0; i < P; ++i)
      for(int k = 1; k <= n; ++k)
        t[k][i][j] = query(t[k][i][j - 1], j - 1);
  itv ed = {1, n};
  for(int i = 1; i <= q; ++i) {
    itv x;
    read(x.l), read(x.r);
    if(x == ed) {
      puts("0");
      continue;
    }
    int ans = 1;
    for(int i = P - 1; ~i; --i) {
      if(!(query(x, i) == ed) && query(x, i).l) 
        x = query(x, i), ans += (1 << i);
    }
    if(!(query(x, 0) == ed)) puts("-1");
    else printf("%d\n",ans);
  }
  return 0;
}

标签:10,ch,const,int,Replace,CF1707E,itv,inline
From: https://www.cnblogs.com/DCH233/p/17087950.html

相关文章

  • 题解 【[USACO23JAN] Find and Replace G】
    problem有一个字符串\(S\),初始时为\(\tt'a'\),现在进行\(n\)次操作,第\(i\)次操作形如:将\(S\)中的所有的字符\(ch_i\)替换为字符串\(T_i\)。然后输出\(S[l......
  • ReplaceGoogleCDN扩展功能使用二:拦截请求域名
    文档说明:只记录关键地方;2023-01-29使用例子:例子:拦截访问域名https://www.jingjingxyk.com更多玩法,可配合content_scripts实现清除内容农场规则例子[{......
  • ReplaceGoogleCDN扩展功能使用一: 修改UserAgent
    文档说明:只记录关键地方;2023-01-29目的:因为屏幕小,移动端使用神马搜索太不方便了,想在PC端使用神马搜索实验:通过chromedev-tools控制台调试发现,把UserAgent修改为移......
  • ReplaceGoogleCDN扩展下载和安装
    ReplaceGoogleCDN扩展下载和安装文档说明:只记录关键地方;2023-01-29在线安装备注:扩展市场的代码版本远落后于源码仓库版本ChromeFirefoxEdge手动安装:Chrome......
  • mysql与lightdb中的insert on duplicate/replace
    最近看pg中insert的实现源码,看到onconflict的excluded优点疑惑,顺带总结下mysql和pg中已存在更新、不存在插入的差异(注:oracle是mergeinto实现)。在mysql中的insertondup......
  • Stata:replace
    replacexm=substr(xm,1,3)+strofreal(_n)//以每个记录xm观测值的第一个字符和行号的组合替换当前的xm的观测值,substr(xm,1,3)截取第一个汉字,strofreal(_n)将行号转为字符......
  • Mysql,replace into,存在则更新,不存在则插入
    REPLACEINTO首先判断数据是否存在;如果不存在,则插入;如果已存在则更新(先删除再插入) 注意:根据主键或唯一索引判断记录是否已存在,所以插入数据的表必须要有主键或者唯......
  • c++ std string replaceAll函数
    std提供的string的replace方法,不太方便stringreplaceAll(string&str,stringoldStr,stringnewStr){string::size_typepos=str.find(oldStr);while(pos......
  • *424. Longest Repeating Character Replacement [Medium]
    424.LongestRepeatingCharacterReplacementYouaregivenastringsandanintegerk.Youcanchooseanycharacterofthestringandchangeittoanyotheru......
  • Search and replace
    Vimprovidesthe:s(substitute)commandforsearchandreplace;thistipshowsexamplesofhowtosubstitute.Onsomesystems,gvimhasFindandReplaceonth......