【51NOD1364】最大字典序排列

來源:互聯網
上載者:User

標籤:for   最大   超過   class   email   排列   date   include   scan   

題面

給出一個1至N的排列,允許你做不超過K次操作,每次操作可以將相鄰的兩個數交換,問能夠得到的字典序最大的排列是什嗎?
例如:N = 5, {1 2 3 4 5},k = 6,在6次交換後,能夠得到的字典序最大的排列為{5 3 1 2 4}。1 <= N <= 100000, 0 <= K <= 10^9

分析

貪心,找第i個位置的數的時候,尋找在i+k的範圍內的最大的數,然後將k更新為這個數的位置減去i,然後把這個數改為一個負數,使它無法再被找到。

關鍵在於如何儲存哪些數已經被選過的資訊。其實和區間交類似,區間交那題維護了在一個範圍內左端點的個數從而能返回左端點位置第k小。

我們也可以維護未被選的元素個數,這樣每次都可以尋找到元素個數為k+1的區間[1,R]的右端點R。再在[1,R]裡尋找最大元素,最後刪除這個元素。

MD少打兩return查一下午 而且這玩意兒居然沒給我炸掉??爆哭

代碼
#include<bits/stdc++.h>using namespace std;#define N 100100#define lc (p<<1)#define rc (p<<1|1)#define mid (t[p].l+t[p].r>>1)int n,k,mx,now,pos,cnt=1;int a[N];struct email{    int l,r,sum,maxx,pos;}t[N*4];inline void pushup(int p){    if(t[lc].maxx>=t[rc].maxx)t[p].maxx=t[lc].maxx,t[p].pos=t[lc].pos;    else t[p].maxx=t[rc].maxx,t[p].pos=t[rc].pos;    t[p].sum=t[lc].sum+t[rc].sum;}inline void build(int p,int l,int r){    t[p].l=l;t[p].r=r;    if(l==r)    {        t[p].maxx=a[l];t[p].sum=1;t[p].pos=l;        return ;    }    int bm=l+r>>1;    build(lc,l,bm);build(rc,bm+1,r);    pushup(p);}inline void update(int p,int x){    if(t[p].l==t[p].r)    {        t[p].maxx=t[p].sum=0;        return ;    }    if(x<=mid)update(lc,x);    if(x>mid)update(rc,x);    pushup(p);}inline void query(int p,int ql,int qr){    if(ql<=t[p].l&&qr>=t[p].r)    {        if(mx<t[p].maxx)pos=t[p].pos,mx=t[p].maxx;        return ;    }    if(ql<=mid)query(lc,ql,qr);    if(qr>mid)query(rc,ql,qr);    pushup(p);}inline int find(int p,int x){    if(t[p].l==t[p].r)return t[p].l;    if(x<=t[lc].sum)return find(lc,x);    if(x>t[lc].sum)return find(rc,x-t[lc].sum);}inline int query_sum(int p,int ql,int qr){    int ret=0;    if(ql<=t[p].l&&qr>=t[p].r)return t[p].sum;    if(ql<=mid)ret+=query_sum(lc,ql,qr);    if(qr>mid)ret+=query_sum(rc,ql,qr);    return ret;}int main(){    scanf("%d%d",&n,&k);    for(int i=1;i<=n;i++)scanf("%d",&a[i]);     build(1,1,n);     while(k>0&&cnt<=n)     {         mx=0;pos=n;         if(cnt+k>=n)query(1,1,n);         else now=find(1,k+1),query(1,1,now);         update(1,pos);k-=query_sum(1,1,pos);         a[pos]=-1;cnt++;         printf("%d\n",mx);     }    for(int i=1;i<=n;i++)        if(a[i]!=-1)             printf("%d\n",a[i]);     return 0;}

 

【51NOD1364】最大字典序排列

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.