• 51nod 1364 最大字典序排列(线段树)



    1364 最大字典序排列
    基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题

    给出一个1至N的排列,允许你做不超过K次操作,每次操作可以将相邻的两个数交换,问能够得到的字典序最大的排列是什么?
    例如:N = 5, {1 2 3 4 5},k = 6,在6次交换后,能够得到的字典序最大的排列为{5 3 1 2 4}。
    Input
    第1行:2个数N, K中间用空格分隔(1 <= N <= 100000, 0 <= K <= 10^9)。
    第2至N + 1行:每行一个数i(1 <= i <= N)。
    Output
    输出共N行,每行1个数,对应字典序最大的排列的元素。
    Input示例
    5 6
    1
    2
    3
    4
    5
    Output示例
    5
    3
    1
    2
    4
    /*
    51nod 1364 最大字典序排列(线段树)
    
    problem:
    给出一个1至N的排列,允许你做不超过K次操作,每次操作可以将相邻的两个数交换,问能够得到的字典序最大的排列是什么?
    例如:N = 5, {1 2 3 4 5},k = 6,在6次交换后,能够得到的字典序最大的排列为{5 3 1 2 4}。
    
    solve:
    贪心的思想.  从1~n维护第i个数尽可能大. 就成了在[i+1,k+i]中查找最大值. 然后把找到的数从后面的数组中删除插到前面.
    因为我的删除是用num来表示,所以每次都要先找到对应区间的边界位置. 然后在计算移动过去需要多少步. 直到操作结束
    
    hhh-2016/09/04-11:16:36
    */
    #pragma comment(linker,"/STACK:124000000,124000000")
    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <cstdio>
    #include <cstring>
    #include <vector>
    #include <math.h>
    #include <queue>
    #include <set>
    #include <map>
    #define lson  i<<1
    #define rson  i<<1|1
    #define ll long long
    #define clr(a,b) memset(a,b,sizeof(a))
    #define scanfi(a) scanf("%d",&a)
    #define scanfs(a) scanf("%s",a)
    #define scanfl(a) scanf("%I64d",&a)
    #define scanfd(a) scanf("%lf",&a)
    #define key_val ch[ch[root][1]][0]
    #define eps 1e-7
    #define inf 0x3f3f3f3f3f3f3f3f
    using namespace std;
    const ll mod = 1000000007;
    const int maxn = 100010;
    const double PI = acos(-1.0);
    int n;
    int a[maxn];
    struct node
    {
        int l,r,mid;
        int pos,num;
        int Max;
    } tree[maxn<<2];
    
    void push_up(int i)
    {
        if(tree[lson].Max >= tree[rson].Max)
        {
            tree[i].Max= tree[lson].Max;
            tree[i].pos = tree[lson].pos;
        }
        else
        {
            tree[i].Max = tree[rson].Max;
            tree[i].pos = tree[rson].pos;
        }
        tree[i].num = tree[lson].num + tree[rson].num;
    }
    
    void build(int i,int l,int r)
    {
        tree[i].l = l,tree[i].r = r;
        tree[i].mid = (l+r) >>1;
        tree[i].num = 0;
        if(l == r && l)
        {
            tree[i].num = 1;
            tree[i].Max= a[l];
            tree[i].pos = l;
            return ;
        }
        build(lson,l,tree[i].mid);
        build(rson,tree[i].mid+1,r);
        push_up(i);
    }
    int tMax,tpos;
    
    void update(int i,int k)
    {
        if(tree[i].l >= k && tree[i].r <= k)
        {
            tree[i].Max = 0;
            tree[i].num = 0;
            return ;
        }
        int mid = tree[i].mid;
        if(k <= mid)
            update(lson,k);
        else
            update(rson,k);
        push_up(i);
        return ;
    }
    void query(int i,int l,int r)
    {
        if(tree[i].l >= l && tree[i].r <= r)
        {
            if(tMax < tree[i].Max)
                tMax = tree[i].Max,tpos = tree[i].pos;
            else if(tMax == tree[i].Max)
                tpos = min(tree[i].pos,tpos);
            return ;
        }
        int mid = tree[i].mid;
        if(l <= mid)
            query(lson,l,r);
        if(r > mid)
            query(rson,l,r);
        push_up(i);
        return ;
    }
    
    int query_x(int i,int k)
    {
        if(tree[i].l == tree[i].r)
        {
            return tree[i].l;
        }
        int mid = tree[i].mid;
        if(tree[lson].num >= k)
           return  query_x(lson,k);
        else
            return query_x(rson,k-tree[lson].num);
        push_up(i);
    }
    
    int query_num(int i,int l,int r)
    {
        if(tree[i].l >= l && tree[i].r <= r)
        {
            return tree[i].num;
        }
        int ans = 0;
        if(l <=tree[i].mid)
            ans += query_num(lson,l,r);
        if(r > tree[i].mid)
            ans += query_num(rson,l,r);
        return ans;
    }
    
    int ans[maxn];
    int main()
    {
        int t;
    //    freopen("in.txt","r",stdin);
        while(scanfi(n) != EOF)
        {
            scanfi(t);
            a[0] = 0;
            for(int i = 1; i <= n; i++)
            {
                scanfi(a[i]);
            }
            build(1,1,n);
            int cnt = 1;
            while(t > 0 && cnt <= n)
            {
                tMax = 0,tpos = n;
                if(cnt + t >= n)
                {
                    query(1,1,n);
                    update(1,tpos);
                    t -= query_num(1,1,tpos);
    
                    printf("%d
    ",tMax);
                    cnt++;
                    a[tpos] = -1;
                }
                else
                {
                    int pos = query_x(1,t+1);
                    query(1,1,pos);
                    update(1,tpos);
                    t -= query_num(1,1,tpos);
                    cnt++;
                    printf("%d
    ",tMax);
                    a[tpos] = -1;
                }
            }
            for(int i = 1; i <= n; i++)
                if(a[i]  !=  -1)
                    printf("%d
    ",a[i]);
        }
        return 0;
    }
    

      

  • 相关阅读:
    GTC China 2016观感
    关于OpenGL的绘制上下文
    Voreen(三) 光线投射参数介绍
    分享一些DICOM数据下载网站
    Voreen (二) 入点出点计算
    Voreen (一) GPU Raycast主流程
    GPU渲染和GDI
    程序媛壮志雄心尝试装机,命运多舛壮志未酬失败告终~
    安装Newton版Glance
    安装Newton版Swift,配合keystone认证
  • 原文地址:https://www.cnblogs.com/Przz/p/5838896.html
Copyright © 2020-2023  润新知