首页 > 其他分享 >ABC262F 题解

ABC262F 题解

时间:2024-07-27 16:52:10浏览次数:17  
标签:rotate int 题解 pos ++ sh erase ABC262F

题面

把“移动 \(a_n\) 至数列头”称为 rotate,删除一项称为 erase

因为要求字典序最小,所以可以逐位贪心。

考虑一个数 \(a_i\) 怎么变成第一个数:

  • 使用 \(n-i\) 次 rotate/erase,再 rotate 一次。删除或移动原来的 \(a_{i+1}\sim a_n\),再移动原来的 \(a_i\)(逐步移动到数列尾,再 rotate 一次)。
  • 使用 \(i-1\) 次 erase,删除 \(a_1\sim a_{i-1}\)(逐步移动到数列头)。

设 \([a,b]_{\min}\) 表示 \(\min_{i=a}^ba_i\),\(id(i)\) 满足 \(a_{id(i)}=i\)。

对于第一种情况:

设 \(pos=id([n-k+1,n]_{\min})\)。

则操作结束后 \(a\) 序列变为 \(a_{pos},a_{b_1},a_{b_2},\cdots,a_{b_k},a_{c_1},a_{c_2},\cdots,a_{c_m}(b_i>pos,c_i<pos,b_i<b_{i+1},c_i<c_{i+1})\)。

因为字典序最小,并且 \(a_{b_i}\) 留与不留不影响操作次数(只是用 rotate 还是 erase 的区别)

所以 \(a_{b_i}\) 要尽量小,所以可以得出 \(a_{b_i}\) 是比 \(a_{b_{i-1}}\) 更靠后而且更大的最小值。

注意到如果 \(a_{b_k}>a_{c_1}\),那么不如对 \(a_{b_k}\) 用一次 erase 直接删掉而不是 rotate(总操作次数不变)。

所以还要满足 \(a_{b_k}<a_{c_1}\)。

所以求出 \(b_i\) 只要用单调栈,插入时 \(j\) 如果栈顶比 \(a_j\) 大就弹出栈顶。

考虑怎么求出 \(c\):同样使用单调栈扫一遍 \([1,pos)\),只是弹出次数限制为 \(pos-(n-k)+1\),如果达到限制就只能插入不能弹出。可以说明这可以求出字典序最小的答案。

别忘了要保证 \(a_{b_k}<a_{c_1}\)。

对于第二种情况:

直接单调栈扫一遍 \([1,n]\),弹出限制为 \(k\)。

输出答案时输出字典序较小的情况就可以了。


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

const int N = 2e5 + 5;
int nxt[N], a[N], n, k;

signed main()
{
    ios::sync_with_stdio(0);cin.tie(0);
    cin >> n >> k;
    for(int i = 1; i <= n; i ++) cin >> a[i];
    int mn = 1e9, id = n + 1;
    for(int i = n - k + 1; i <= n; i ++)
        if(a[i] < mn) mn = a[i], id = i;
    int d = id - (n - k + 1);
    int s[N] = {}, sh = 0;
// case1
    int p = 1, cnt = 0;
    for(p = 1, cnt = 0; p < id; p ++)
    {
        while(sh && cnt < d && a[s[sh]] > a[p]) sh --, cnt ++;
        s[++sh] = p;
    }
    int ans[N] = {}, h = 0;
    for(p = id; p <= n; p ++)
    {
        if(a[p] > a[s[1]]) continue;
        while(h && a[ans[h]] > a[p]) h --;
        ans[++h] = p;
    }
    for(int i = 1; i <= sh; i ++) ans[++h] = s[i];

// case2
    sh = 0;
    s[++sh] = 1;
    p = 1, cnt = 0;
    for(p = 2, cnt = 0; p <= n; p ++)
    {
        while(sh && cnt < k && a[s[sh]] > a[p]) sh --, cnt ++;
        s[++sh] = p;
    }
    while(cnt < k) sh --, cnt ++;

    bool eq = 1;
    bool typ = 0;
    int len = min(h, sh);
    for(int i = 1; i <= len; i ++)
        if(a[ans[i]] < a[s[i]]) {typ = 1; eq = 0; break;}
        else if(a[ans[i]] > a[s[i]]) {eq = 0; typ = 0; break;}
    if(eq && h < sh) typ = 1;
    
    if(!typ) for(int i = 1; i <= sh; i ++) cout << a[s[i]] << " ";
    else for(int i = 1; i <= h; i ++) cout << a[ans[i]] << " ";

    return 0;
}

标签:rotate,int,题解,pos,++,sh,erase,ABC262F
From: https://www.cnblogs.com/adam01/p/18327141

相关文章

  • ABC261F 题解
    题面注意到如果两个球\(i,j\)有\(i<j,x_i>x_j\),那么这两个球一定会交换。所以要交换\(x\)的逆序对数次。但是相同颜色交换没有代价,所以答案是\(x\)的逆序对数减去满足\(c_i=c_j,i<j,x_i>x_j\)的\((i,j)\)对的数量。可以对每个\(j\)都求一遍满足\(c_i=j\)的\(......
  • ABC264F 题解
    题面注意到操作只对当前行/列有效,所以只要记录当前所在行和列是否有被操作。设\(f(i,j,x,y)\)表示到了位置\((i,j)\),第\(i\)行是否被操作,第\(j\)列是否被操作的最小代价。转移:设\(col=c(i,j)\oplusx\oplusy\)。\[\begin{aligned}f(i+1,j,x2,y)&\xleftarrow......
  • ABC265F 题解
    题面\(O(nd^2)\)考虑\(f(i,j,k)\)表示dp到第\(i\)维,距离\(p,q\)曼哈顿距离\(j,k\)的方案数。考虑朴素转移:设\(dis=|p_{i+1}-q_{i+1}|\)。\[\begin{aligned}f(i+1,j+t,k+dis-t)&\getsf(i,j,k)&(0\leqt\leqdis)\quad&(1)\\f(i+1,j+d+t,k+t)&\ge......
  • 题解:CF1608F MEX counting
    题解:CF1608FMEXcounting与其他题解不同,本篇题解是运用辅助数组$g$来解决问题。虽然代码可能要繁琐一点,但是辅助数组的思路适用范围更广一点。首先还是转化为前$i$个数的$mex$在区间$[l_i,r_i]$内。我们用dp数组$f_{i,x,c}$表示处理到了第$i$个数,当前的mex为......
  • CF605E Intergalaxy Trips 题解
    Description\(n\)个点的有向完全图。\(i\toj\)的边每天出现的概率均为\(p_{i,j}\),若\(i=j\),有\(p_{i,j}=1\)。每天可以选择一条存在的出边走过去或停留在原地不动。求最优策略下从\(1\)到\(n\)的期望天数。\(n\le10^3\)。Solution设\(f_i\)表示\(i\)......
  • [题解]P2672 [NOIP2015 普及组] 推销员
    P2672[NOIP2015普及组]推销员为了便于操作,将住户信息按疲劳值从大到小排序。那么对于选\(X\)个住户,有\(2\)种情况:选疲劳值前\(X\)大的住户,答案即为\(\sum\limits_{i=1}^Xa[i]+2\times\max\limits_{i=1}^Xs[i]\)。选疲劳值前\(X-1\)大的住户,然后在剩下的住户中,距离比......
  • 《梦醒蝶飞:释放Excel函数与公式的力量》21.2 问题解决策略
     第21章:综合案例分析 21.2问题解决策略在综合案例分析中,解决问题的策略涉及多个步骤,从问题的识别、分析到实施解决方案和评估效果。通过系统的方法和多学科的知识,可以高效地解决复杂的问题。以下将介绍一个具体案例,并通过详细的步骤展示如何制定和实施问题解决策略。案例......
  • Codeforce 962 Div3 C~E 题解
    C题目大意​给定两个字符串a,b,q个询问,每次操作可以将a[i]赋值为任意一个字符,每次询问[l,r]区间内使得sorted(a[l,r])==sorted(b[l,r])的最小操作次数分析​ 不妨先考虑一个区间如何判断sorted后的字串是否相等,发现跟字符出现的次数有关,于是考虑前缀和预处理每一个26......
  • ABC273F Hammer 题解
    ABC273FHammer题解题目大意数轴上有\(n\)个锤子和\(n\)堵墙,第\(i\)个锤子位于\(x_i\),第\(i\)堵墙位于\(y_i\),第\(i\)个锤子可以对应的敲开第\(i\)堵墙。以原点为起点,给定终点\(t\),问最少移动多少个单位长度才能走到\(t\)。必须拿到对应锤子敲开墙才能走过这堵......
  • Codeforces Round 962 (Div. 3) 题解
    A.Legshttps://codeforces.com/contest/1996/problem/A翻译:农夫约翰的农场又迎来了美好的一天。农夫约翰来到农场后,数了数n条腿。众所周知,农场里只住着鸡和牛,一只鸡有2条腿,而一头牛有4条腿。假设约翰农场主数清了所有动物的腿,那么他的农场里最少有多少动物?思路求最少......