Submission #50624050


Source Code Expand

#include <bits/stdc++.h>
#include <atcoder/modint>
const int MOD=998244353;
using mint = atcoder::static_modint<MOD>;
using namespace std;

typedef long long ll;
#define rep(i,a,n) for (ll i=a;i<(ll)(n);i++)
#define per(i,a,n) for (ll i=n;i-->(ll)(a);)

#define SEG_ROOT(r) r,0,n+1
#define SEG_L seg[o].l
#define SEG_R seg[o].r
#define mid (l+r)/2
#define SEG_L_CHILD SEG_L,l,mid
#define SEG_R_CHILD SEG_R,mid,r

struct node{
  int l=-1;
  int r=-1;
  int v=0;
};
vector<node>seg;
int newnode(){
  int t=seg.size();
  seg.push_back(node{-1,-1,0});
  return t;
}

ll read(){ll r;scanf("%lld",&r);return r;}
int n;
vector<int>p;

void pick(vector<int>pos){
  vector<int>isst(n,0);
  vector<pair<int,int> > st;
  for(auto i:pos) {
    st.push_back({p[i],i});
    isst[i]=true;
  }
  sort(begin(st),end(st),[](auto x,auto y){return y<x;});
  for(auto [v,stp]:st) {
    rep(i,stp,n){
      if(i!=stp and isst[i]) break; // 到下一个起点了
      printf("%d ",p[i]);
    }
  }
}

int query(int o,int l,int r,int ql,int qr){ // [l,r) [ql,qr)
  if(o==-1) return 0;
  if(ql <= l and r <= qr) return seg[o].v;
  int ret=0;
  if(ql < mid) ret += query(SEG_L_CHILD,ql,qr);
  if(qr > mid) ret += query(SEG_R_CHILD,ql,qr);
  return ret;
}

int add(int o,int l,int r,int p){
  assert(1<=p and p<=n);
  if(l+1==r){
    assert(o==-1);
    int v=newnode();
    seg[v].v=1;
    return v;
  }
  int v=newnode();
  if(o!=-1) { // clone
    seg[v].l=seg[o].l;
    seg[v].r=seg[o].r;
  }

  if(p< mid) seg[v].l=add(seg[v].l,l,mid,p);
  if(p>=mid) seg[v].r=add(seg[v].r,mid,r,p);

  seg[v].v = 0;
  if(seg[v].l!=-1) seg[v].v+=seg[seg[v].l].v;
  if(seg[v].r!=-1) seg[v].v+=seg[seg[v].r].v;
  return v;
}

int main(){
  n=read();
  int k=read();
  p.resize(n);
  rep(i,0,n) p[i]=read();
  if(k>=p[0]) { // 一定变 开头选1~k
    vector<int>pos;
    rep(i,0,n) if(p[i] <= k) pos.push_back(i);
    pick(pos);
    return 0;
  }

  vector<int> sz(n,0);
  sz[0]=1;
  vector<int> pre(n,0); // 最长严格下降上一个节点
  vector<int> idx; // val, 值严格下降, 个数=下标+1
  idx.push_back(0);
  rep(i,1,n) if(p[i] < p[0]){
    int l=0;
    int r=idx.size();
    while(r-l>1){ (p[idx[mid]] > p[i]?l:r) = mid; }
    pre[i] = idx[l];
    sz[i]=r+1;
    if(r < (int)idx.size()) {
      if(p[i] > p[idx[r]]) idx[r]=i;
    }else{
      idx.push_back(i);
    }
  }
  rep(i,0,n) if(sz[i] >= k) { // 可以完全不变
    pick({0});
    return 0;
  }
  vector<int> roots={-1}; // [n, n-1,....]
  array<int,3> best={-1,-1,-1}; // 后缀选择起始下标, 选点个数, 前缀单调下降最后一个起始值下标(比较值下标)
  per(i,0,n) {
    if(p[i]<=p[0]){
      int s = sz[i];
      assert(s<k);
      // 后面 选 k-s 个 < p[i]的
      int c=query(SEG_ROOT(roots.back()),1,p[i]);
      if(c >= k-s) {// 能选出k-s个<p[i]
        int l=0;
        int r=roots.size()-1;
        while(r-l>1) (query(SEG_ROOT(roots[mid]),1,p[i]) >= k-s ?r:l)=mid;
        // {n-r,i}: n-r开始<p[i]}
        if(n-r > best[0]){
          best = {n-r,k-s,(int)i};
        }else if(n-r == best[0]){ // 起始相等 待选点越少越好
          if(k-s < best[1]) {
            best = {n-r,k-s,(int)i};
          }
        }
      }
      roots.push_back(add(SEG_ROOT(roots.back()),p[i]));
    }else{
      roots.push_back(roots.back());
    }
  }
  assert(best[0] != -1);
  auto [si,_,pi] = best;
  assert(pi<si);
  vector<int> pos;
  rep(i,si,n) if(p[i]<p[pi]) pos.push_back(i);
  int i=pi;
  while(true){
    pos.push_back(i);
    if(i==0) break;
    i=pre[i];
  }
  assert((int)pos.size()==k);
  pick(pos);
  return 0;
}

Submission Info

Submission Time
Task F - Permutation Division
User cromarmot
Language C++ 20 (gcc 12.2)
Score 900
Code Size 3605 Byte
Status AC
Exec Time 747 ms
Memory 56668 KiB

Compile Error

Main.cpp: In function ‘ll read()’:
Main.cpp:30:21: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
   30 | ll read(){ll r;scanf("%lld",&r);return r;}
      |                ~~~~~^~~~~~~~~~~

Judge Result

Set Name Sample All
Score / Max Score 0 / 0 900 / 900
Status
AC × 3
AC × 40
Set Name Test Cases
Sample s1.txt, s2.txt, s3.txt
All 01.txt, 02.txt, 03.txt, 04.txt, 05.txt, 06.txt, 07.txt, 08.txt, 09.txt, 10.txt, 11.txt, 12.txt, 13.txt, 14.txt, 15.txt, 16.txt, 17.txt, 18.txt, 19.txt, 20.txt, 21.txt, 22.txt, 23.txt, 24.txt, 25.txt, 26.txt, 27.txt, 28.txt, 29.txt, 30.txt, 31.txt, 32.txt, 33.txt, 34.txt, 35.txt, 36.txt, 37.txt, s1.txt, s2.txt, s3.txt
Case Name Status Exec Time Memory
01.txt AC 2 ms 3944 KiB
02.txt AC 1 ms 3748 KiB
03.txt AC 2 ms 3812 KiB
04.txt AC 44 ms 6784 KiB
05.txt AC 51 ms 8444 KiB
06.txt AC 31 ms 5196 KiB
07.txt AC 43 ms 6964 KiB
08.txt AC 45 ms 8000 KiB
09.txt AC 40 ms 6596 KiB
10.txt AC 2 ms 3892 KiB
11.txt AC 2 ms 4020 KiB
12.txt AC 2 ms 4032 KiB
13.txt AC 2 ms 3820 KiB
14.txt AC 4 ms 4440 KiB
15.txt AC 2 ms 3988 KiB
16.txt AC 623 ms 55788 KiB
17.txt AC 747 ms 55844 KiB
18.txt AC 387 ms 31112 KiB
19.txt AC 216 ms 56476 KiB
20.txt AC 31 ms 6448 KiB
21.txt AC 278 ms 55892 KiB
22.txt AC 158 ms 56284 KiB
23.txt AC 375 ms 56360 KiB
24.txt AC 56 ms 14256 KiB
25.txt AC 35 ms 6464 KiB
26.txt AC 220 ms 55976 KiB
27.txt AC 309 ms 55888 KiB
28.txt AC 193 ms 56176 KiB
29.txt AC 366 ms 56104 KiB
30.txt AC 40 ms 6832 KiB
31.txt AC 236 ms 56668 KiB
32.txt AC 243 ms 56236 KiB
33.txt AC 397 ms 56244 KiB
34.txt AC 1 ms 3952 KiB
35.txt AC 28 ms 8524 KiB
36.txt AC 30 ms 8516 KiB
37.txt AC 38 ms 7196 KiB
s1.txt AC 1 ms 3728 KiB
s2.txt AC 1 ms 3728 KiB
s3.txt AC 1 ms 3564 KiB