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 |
|
|
| 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 |