Div3
CF 1893 A
题目描述
有以下操作:
- 选择数组 \(A\) 的一个固定点 \(x\)。固定点是指满足 \(A_x=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\) 中使得最终的 \(\text{LIS}(A)\) 尽可能小。
思路
最终肯定是使最终的 \(\text{LIS}\) 与原来相同。很明显有以下构造方法:
- 从大到小枚举 \(B\) 中的数,找到 \(A\) 中第一个小于它的,并把它插在前面。
空间复杂度 \(O(N+M)\),时间复杂度 \(O(M\log M)\)。
代码
#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;
}
 
                    
                
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号