老夫聊发少年狂,碱金属,丢池塘。浮溶游响,激起千朵|

Yaosicheng124

园龄:1年2个月粉丝:8关注:11

Div3

CF 1893 A

题目描述

有以下操作:

  • 选择数组 A 的一个固定点 x。固定点是指满足 Ax=x 的点。
  • A 循环左移 x 次。

求数组 B 有没有可能是通过某个 A 执行 k 次操作得到的。

思路

可以发现,上次选择的固定点 x 一定被转到了最后面。按题意模拟即可。

时空复杂度均为 O(N)

代码

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

const int MAXN = 200001;

int t, n, k, a[MAXN];
bool vis[MAXN];

void Solve() {
  cin >> n >> k;
  for(int i = 1; i <= n; ++i) {
    cin >> a[i];
    vis[i] = 0;
  }
  for(int i = 1, p = n; i <= k && !vis[p]; ++i) {
    if(a[p] > n) {
      cout << "No\n";
      return;
    }
    vis[p] = 1;
    p = p + n - a[p] - (p + n - a[p] > n) * n;
  }
  cout << "Yes\n";
}

int main() {
  ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
  for(cin >> t; t--; Solve()) {
  }
  return 0;
}

CF 1893 B

题目描述

给定数组 A,B,你要把 B 中的数字插入到 A 中使得最终的 LIS(A) 尽可能小。

思路

最终肯定是使最终的 LIS 与原来相同。很明显有以下构造方法:

  • 从大到小枚举 B 中的数,找到 A 中第一个小于它的,并把它插在前面。

空间复杂度 O(N+M),时间复杂度 O(MlogM)

代码

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

const int MAXN = 200001;

int t, n, m, a[MAXN], b[MAXN];

void Solve() {
  cin >> n >> m;
  for(int i = 1; i <= n; ++i) {
    cin >> a[i];
  }
  for(int i = 1; i <= m; ++i) {
    cin >> b[i];
  }
  sort(b + 1, b + m + 1, greater<int>());
  int i = 1, j = 1;
  for(; i <= n; ++i) {
    for(; j <= m && b[j] >= a[i]; ++j) {
      cout << b[j] << " ";
    }
    cout << a[i] << " ";
  }
  for(; j <= m; ++j) {
    cout << b[j] << " ";
  }
  cout << "\n";
}

int main() {
  ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
  for(cin >> t; t--; Solve()) {
  }
  return 0;
}

本文作者:yaosicheng124

本文链接:https://www.cnblogs.com/yaosicheng124/p/18473859

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Yaosicheng124  阅读(6)  评论(0编辑  收藏  举报
  1. 1 Minecraft C418
Minecraft - C418
00:00 / 00:00
An audio error has occurred.

暂无歌词

加载中…

{{tag.name}}

{{tran.text}}{{tran.sub}}
无对应文字
有可能是
{{input}}
尚未录入,我来提交对应文字
评论
收藏
关注
推荐
深色
回顶
收起
点击右上角即可分享
微信分享提示