首页 > 其他分享 >2024初秋集训——提高组 #36

2024初秋集训——提高组 #36

时间:2024-10-17 19:59:37浏览次数:1  
标签:return int 36 2024 dep MAXN it2 id 初秋

C. 经典字符串问题

题目描述

给定一个排列,对于每个数,我们都可以把它看作一个字符串。请求出 \([l,r]\) 中字典序第 \(k\) 小的数是什么。

思路

我们可以建一个可持久化字典树,上面记录每个前缀的每个数。这里我们要在这些数的后面插入 \(-1\),使得其长度相等,并方便我们判断字典序。

时空复杂度均为 \(O((N+Q)\log A_i)\)。

代码

#include<bits/stdc++.h>
using namespace std;

const int MAXN = 100005;

int Pow10[6];

struct Persistent_Trie {
  int tot = 1, ROOT[MAXN], son[11][10 * MAXN], cnt[10 * MAXN];
  void Insert(int x, int y, int val) {
    ROOT[x] = ++tot;
    int u = tot, v = ROOT[y], res = 0;
    bool op = 0;
    for(int i = 5; i >= 0; --i) {
      int num = val / Pow10[i] % 10 + 1;
      if(num > 1 || op) {
        cnt[u] = cnt[v] + 1;
        op = 1;
        for(int j = 0; j <= 10; ++j) {
          son[j][u] = son[j][v];
        }
        u = son[num][u] = ++tot, v = son[num][v];
      }else {
        res++;
      }
    }
    for(int i = 1; i <= res; ++i) {
      cnt[u] = cnt[v] + 1;
      for(int j = 0; j <= 10; ++j) {
        son[j][u] = son[j][v];
      }
      u = son[0][u] = ++tot, v = son[0][v];
    }
    cnt[u] = cnt[v] + 1;
  }
  int Find(int l, int r, int k) {
    if(k > r - l + 1) {
      return -1;
    }
    int u = ROOT[l - 1], v = ROOT[r], ret = 0;
    for(int i = 5; i >= 0; --i) {
      int res = 0;
      for(int j = 0; j <= 10; ++j) {
        if(res + cnt[son[j][v]] - cnt[son[j][u]] >= k) {
          k -= res;
          if(!j) {
            return ret;
          }
          ret = 10 * ret + j - 1;
          u = son[j][u], v = son[j][v];
          break;
        }
        res += cnt[son[j][v]] - cnt[son[j][u]];
      }
    }
    return ret;
  }
}tr;

int n, q;

int main() {
  ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
  cin >> n >> q;
  Pow10[0] = 1;
  for(int i = 1; i <= 5; ++i) {
    Pow10[i] = Pow10[i - 1] * 10;
  }
  for(int i = 1, x; i <= n; ++i) {
    cin >> x;
    tr.Insert(i, i - 1, x);
  }
  for(int i = 1, l, r, k; i <= q; ++i) {
    cin >> l >> r >> k;
    cout << tr.Find(l, r, k) << "\n";
  }
  return 0;
}

D. 圆与圆之间的距离是不能一概而论的

题目描述

给定 \(N\) 个圆,这些圆之间的关系只有分离,包含两种(不会相切,相交)。我们定义两个圆的距离为其间一条路径(可以弯曲)穿过圆弧数量的最小值(不包含端点)。有 \(Q\) 个查询,每次查询两个圆之间的距离。

思路

我们可以先对这些圆建树,一个圆的父亲为包含它的圆中半径最小的那个。求其在树上的距离即可。而难点就在于建树。

我们使用扫描线求解。我们可以将一个圆拆分成左右两半,每次找父亲时用 set 找到其左右第一个圆弧。如果左弧左边还是左弧,那么父亲就是此弧对应的圆。若是右弧,那么父亲为此弧的父亲。

空间复杂度 \(O(N)\),时间复杂度 \(O(N\log N)\)。

代码

#include<bits/stdc++.h>
using namespace std;
using pii = pair<int, int>;
using ld = long double;

const int MAXN = 300005;

struct Node {
  int x, y, r, id;
}s[MAXN];

int posx;

ld inter(int i, int x) {
  int id = abs(i);
  return s[id].y + (i < 0 ? -1.0l : 1.0l) * sqrt((ld)(1ll * s[id].r * s[id].r - 1ll * (x - s[id].x) * (x - s[id].x)));
}

struct cmp {
  bool operator()(int a, int b) const {
    return inter(a, posx) < inter(b, posx) || (inter(a, posx) == inter(b, posx) && a < b);
  }
};

int n, q, f[18][MAXN], pos[MAXN], dep[MAXN];
vector<int> e[MAXN], X, vec[2 * MAXN];
vector<pii> ve[2 * MAXN];
set<int, cmp> S;

int LCA(int u, int v) {
  if(dep[u] < dep[v]) {
    swap(u, v);
  }
  int d = dep[u] - dep[v];
  for(int i = 17; i >= 0; --i) {
    if((d >> i) & 1) {
      u = f[i][u];
    }
  }
  if(u == v) {
    return u;
  }
  for(int i = 17; i >= 0; --i) {
    if(f[i][u] != f[i][v]) {
      u = f[i][u], v = f[i][v];
    }
  }
  return f[0][u];
}

void dfs(int u) {
  dep[u] = dep[f[0][u]] + 1;
  for(int i = 1; i <= 17; ++i) {
    f[i][u] = f[i - 1][f[i - 1][u]];
  }
  for(int v : e[u]) {
    dfs(v);
  }
}

int main() {
  ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
  freopen("circle.in", "r", stdin);
  freopen("circle.out", "w", stdout);
  cin >> n;
  for(int i = 1; i <= n; ++i) {
    cin >> s[i].x >> s[i].y >> s[i].r;
    X.emplace_back(s[i].x - s[i].r);
    X.emplace_back(s[i].x + s[i].r);
  }
  sort(X.begin(), X.end()), X.erase(unique(X.begin(), X.end()), X.end());
  for(int i = 1; i <= n; ++i) {
    int l = lower_bound(X.begin(), X.end(), s[i].x - s[i].r) - X.begin() + 1;
    int r = lower_bound(X.begin(), X.end(), s[i].x + s[i].r) - X.begin() + 1;
    ve[l].emplace_back(i, 1);
    ve[r].emplace_back(i, -1);
    vec[l].emplace_back(i);
  }
  for(int i = 1; i <= X.size(); ++i) {
    posx = X[i - 1];
    for(auto [x, op] : ve[i]) {
      if(op == 1) {
        S.insert(x);
        S.insert(-x);
      }else {
        S.erase(x);
        S.erase(-x);
      }
    }
    for(int x : vec[i]) {
      auto it = S.find(-x), it2 = S.upper_bound(x);
      int id = 0;
      if(it != S.begin()) {
        it = prev(it);
        if(*it < 0) {
          id = -*it;
        }else {
          id = f[0][*it];
        }
      }
      if(it2 != S.end()) {
        if(*it2 > 0 && (!id || s[id].r > s[*it2].r)) {
          id = *it2;
        }
        if(*it2 < 0 && (!id || s[id].r > s[f[0][-*it2]].r)) {
          id = f[0][-*it2];
        }
      }
      f[0][x] = id;
      e[id].emplace_back(x);
    }
  }
  dfs(0);
  cin >> q;
  for(int i = 1, u, v; i <= q; ++i) {
    cin >> u >> v;
    int l = LCA(u, v);
    cout << dep[u] + dep[v] - 2 * dep[l] - (u != l) - (v != l) << "\n";
  }
  return 0;
}

标签:return,int,36,2024,dep,MAXN,it2,id,初秋
From: https://www.cnblogs.com/yaosicheng124/p/18472967

相关文章

  • 多校A层冲刺NOIP2024模拟赛08
    挂分了,垫底啦!!!rank8挂成rank27啦!!!rank27,T128,T20,T30,T40T2内存限制256MB,我打了一个257MB的,然后MLE了。T3暴力挂了9pts?T1传送(teleport)是简单题,但我不会对\(X,Y\)分开看,如果我们在最优解中⾛了某⼀步,可以看做是在对应维度上⾛了⼀段。那么这⼀段上的点可以看做是依......
  • 2024年计算机视觉与图像处理国际学术会议 (CVIP 2024) 2024 International Conference
    文章目录一、会议详情二、重要信息三、大会介绍四、出席嘉宾五、征稿主题六、咨询一、会议详情二、重要信息大会官网:https://ais.cn/u/vEbMBz提交检索:EICompendex、IEEEXplore、Scopus三、大会介绍2024年计算机视觉与图像处理国际学术会议(CVIP2024)将于2024......
  • 第六届土木建筑与城市工程国际学术会议(ICCAUE 2024) 2024 6th International Conferenc
    文章目录一、会议详情二、重要信息三、大会介绍四、出席嘉宾五、征稿主题六、咨询一、会议详情二、重要信息大会官网:https://ais.cn/u/vEbMBz提交检索:EICompendex、IEEEXplore、Scopus三、大会介绍第六届土木建筑与城市工程国际学术会议(ICCAUE2024)将于2024年......
  • 20241017 练习记录
    今天duel了一整天CF的题!虽然都是800-2000的……CF1131C平。开始其实就猜到结论了,但感觉很假就没想下去,还去写什么二分答案随机化,唐完了。结论题,维护双端队列,an从队头进,an-1从队尾,an-2从队头……以此类推,正确性显然。CF888D输!想复杂了……对k分类讨论计算即可......
  • 20222310 2024-2025-1 《网络与系统攻防技术》实验二实验报告
    一、实验内容1.使用netcat获取主机操作Shell,cron启动某项任务(任务自定)。PS:cron是linux下用来周期性的执行某种任务或等待处理某些事件的一个守护进程2.使用socat获取主机操作Shell,任务计划启动。3.使用MSFmeterpreter生成后门,利用ncat或socat传送到主机并运行获取主机Shell......
  • IntelliJ IDEA 2024 安装使用 (附加激活码、补丁,亲测有效!)
    第一步:下载IDEA安装包访问IDEA官网,下载IDEA2024.1.4版本的安装包,下载链接如下:idea官方链接也可以在这里点击下载idea下载idea第二步:安装IDEA点击xx关掉程序!第三步:下载补丁下载地址(里面包含激活码)https://pan.quark.cn/s/9dbfe698c064补丁下载成功后,......
  • 2024初秋集训——提高组 #40
    B.艰难睡眠题目描述一天有\(M\)分钟,依次编号\(1,2,\dots,M\)。有\(N\)个人,第\(i\)个人会在\(A_i\)分钟开始吵闹,持续\(B_i\)分钟(可能会到第二天)。现在你想要睡连续\(k\)分钟,所以你要使得这\(k\)分钟内没人吵闹。你可以花费\(c_{i,j}\)的代价让第\(i\)个人从......
  • 20241017
    袜子分配(socks)我们可以考虑一下我们是怎么暴搜的,我们搜出一个\(2\timesn\)长度的序列,然后枚举每相邻两个数字,判断是不是合法的,那么也就是说,一个数字想合法,他必须精准的落在这个序列中的一个位置,那么概率是\(2\timesn-1\),有\(n\)对数字,那么期望就是\(n\div......
  • CSP2024 前集训:多校A层冲刺NOIP2024模拟赛08
    前言光顾着想T2了,但是不知道哪儿假了,只有\(\dfrac{n}{k}\le5\)的点是对的,然后居然只有二十分,发现数据放错了,找喵喵改了成五十了。然后T1因为重边挂没了。T3没调出来,确切的说是省的时间不多了打不完,就写了个部分分。T4咕了。机房凳子没靠椅,一直坐着腰快折了肿么办。......
  • 2024年软件设计师中级(软考中级)详细笔记【6】结构化开发方法(分值3~4)
    目录前言6.1系统分析与设计概述6.1.2系统设计的基本原理6.1.3系统总体结构设计6.1.4系统文档6.2.2数据流图6.2.3数据字典(DD)6.5用户界面设计6.5.1用户界面设计的黄金原则杂题习题:结语前言在备考软件设计师中级考试的过程中,我遇到了些许挑战,也收获了宝贵的......