arc206d - LIS ∩ LDS

Problem

Problem Statement

Among the elements of a permutation P = ( P 1 , ... , P N ) P = (P_1, \dots, P_N) P=(P1,...,PN) of ( 1 , ... , N ) (1, \dots, N) (1,...,N), those that satisfy the following condition are called good elements:

  • The element can be included in both a longest increasing subsequence and a longest decreasing subsequence of P P P.

You are given integers N N N and K K K. Determine whether there exists a permutation P P P of ( 1 , ... , N ) (1, \dots, N) (1,...,N) such that there are exactly K K K good elements, and if it exists, find one.

Answer for T T T test cases.

Constraints

  • All input values are integers
  • 1 ≤ T ≤ 2 × 10 5 1 \le T \le 2 \times 10^5 1≤T≤2×105
  • 1 ≤ N ≤ 2 × 10 5 1 \le N \le 2 \times 10^5 1≤N≤2×105
  • 0 ≤ K ≤ N 0 \le K \le N 0≤K≤N
  • The sum of N N N over all test cases does not exceed 2 × 10 5 2 \times 10^5 2×105.

Translation

题目描述

在 ( 1 , ... , N ) (1, \dots, N) (1,...,N) 的排列 P = ( P 1 , ... , P N ) P = (P_1, \dots, P_N) P=(P1,...,PN) 中,满足以下条件的元素被称为"好元素":

  • 该元素可以同时包含在 P P P 的一个最长上升子序列(LIS)和一个最长下降子序列(LDS)中。

给定整数 N N N 和 K K K。请判断是否存在一个 ( 1 , ... , N ) (1, \dots, N) (1,...,N) 的排列 P P P,使得其中恰好包含 K K K 个好元素。如果存在,请输出该排列。

本题包含 T T T 组测试用例。

约束条件

  • 所有输入值均为整数
  • 1 ≤ T ≤ 2 × 10 5 1 \le T \le 2 \times 10^5 1≤T≤2×105
  • 1 ≤ N ≤ 2 × 10 5 1 \le N \le 2 \times 10^5 1≤N≤2×105
  • 0 ≤ K ≤ N 0 \le K \le N 0≤K≤N
  • 所有测试用例中 N N N 的总和不超过 2 × 10 5 2 \times 10^5 2×105。

Solutions

Approach 1

分类讨论 + 构造。原本还以为是分析性质的大构造,结果半天分析不出来性质。

首先,考虑 N N N 和 K K K 足够大的时候,如果你能在此时看出一个构造方案,那么这题就不难。

显然,可以让 1 \\sim K 按 K , K − 1 , ⋯   , 1 K,K-1,\cdots,1 K,K−1,⋯,1 的顺序排在最前面,然后其余按 K + 1 , K + 2 , ⋯   , N K+1,K+2,\cdots,N K+1,K+2,⋯,N 的顺序排在后面,这就是一个足够的构造。

现在分析有哪些 N N N 和 K K K 取值的边界,这里就是试,反正我做的时候就是试出来的:

  1. 当 K > 1 K > 1 K>1 ,任意 N N N 都可以使用上述。

  2. 当 K = 1 K = 1 K=1 ,此时又分为三种:

    1. N = 1 N = 1 N=1 ,简单。
    2. K ⩾ 5 K \geqslant 5 K⩾5 ,此时的构造形式形如 2 , N , 3 , 1 , 4 , ⋯   , N − 1 2,N,3,1,4,\cdots,N-1 2,N,3,1,4,⋯,N−1 。
    3. 其余不合法。
  3. 当 K = 0 K = 0 K=0 ,此时又分为两种:

    1. N ⩾ 8 N \geqslant 8 N⩾8 ,此时构造形式形如 3 , 4 , N , N − 1 , 2 , 1 , 5 , 6 , ⋯   , N − 2 3,4,N,N-1,2,1,5,6,\cdots,N-2 3,4,N,N−1,2,1,5,6,⋯,N−2 。
    2. 其余不合法。

确认了一下题解,基本完全一样的形式 - Editorial - AtCoder Regular Contest 206 (Div. 2)

本身以为是分析一个点同时处于递增和递降有什么性质,结果就是基本的大分类讨论和试。

Code
cpp 复制代码
#include<bits/stdc++.h>
using namespace std;

std::mt19937 rng(std::random_device{}());
typedef long double ld;
typedef long long ll;
typedef unsigned long long ull;

const int mod = 998244353;
const double ept = 1e-9;

#define db(x...) { do { cerr << #x << " -> "; err(x); } while (0); }
#define dbv(vec) { cout << #vec << ": "; for(auto &v: vec) { cout << v << ' '; } cout << endl; }
void err() { cerr << endl; } template<class T, class... Ts> void err(const T& arg, const Ts&... args) { cerr << arg << ""; err(args...); }

int n, k;

void solve(int T) {
  cin >> n >> k;

  vector<int> ans;
  if(k == 0) {
    if(n >= 8) {
      ans.push_back(3);
      ans.push_back(4);
      ans.push_back(n);
      ans.push_back(n-1);
      ans.push_back(2);
      ans.push_back(1);
      for(int i=5; i<n-1; i++) ans.push_back(i);
    }
  }
  else if(k == 1) {
    if(n == 1) ans.push_back(1);
    else if(n >= 5) {
      ans.push_back(2);
      ans.push_back(n);
      ans.push_back(3);
      ans.push_back(1);
      for(int i=4; i<n; i++) ans.push_back(i);
    }
  }
  else {
    for(int i=k; i>=1; i--) ans.push_back(i);
    for(int i=k+1; i<=n; i++) ans.push_back(i);
  }

  if(ans.size() < n) cout << -1;
  else for(auto &u: ans) cout << u << ' ';
  cout << endl;
}

void init() {}

signed main() {
    //freopen("1.in", "r", stdin);
    //freopen("1.out", "w", stdout);
    //cout.flags(ios::fixed); cout.precision(8);
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    init();
    int T_=1;
    std::cin >> T_;
    for(int _T=1; _T<=T_; _T++) { solve(_T); }
    return 0;
}
相关推荐
等等小何2 小时前
leetcode1593拆分字符串使唯一子字符串数目最大
算法
王老师青少年编程3 小时前
2025年12月GESP(C++二级): 环保能量球
c++·算法·gesp·csp·信奥赛·二级·环保能量球
weixin_433417673 小时前
Canny边缘检测算法原理与实现
python·opencv·算法
CoderCodingNo3 小时前
【GESP】C++五级真题(贪心思想考点) luogu-P11960 [GESP202503 五级] 平均分配
开发语言·c++·算法
POLITE34 小时前
Leetcode 76.最小覆盖子串 JavaScript (Day 6)
javascript·算法·leetcode
一条大祥脚5 小时前
26.1.1
数据结构·算法
csuzhucong5 小时前
圆柱三阶魔方、六棱柱魔方
算法
mit6.8245 小时前
vector<int> dfs
算法