• ZSTU OJ 4272 最佳淘汰算法


    线段树。

    处理出每个位置下一个位置是哪里。然后搞个线段树找一下最大值就可以了。

    #include<map>
    #include<set>
    #include<ctime>
    #include<cmath>
    #include<queue>
    #include<string>
    #include<stack>
    #include<vector>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<functional>
    using namespace std;
     
    int n,m,a[500010];
    bool In[100010];
     
    int Seg[400010],nx[500010],p[500010];
    int POS,sx[500010],A[500010];
     
    void update(int p,int val,int l,int r,int rt)
    {
        if(l==r)
        {
            Seg[rt]=val;
            return ;
        }
     
        int m=(l+r)/2;
     
        if(p>=l&&p<=m) update(p,val,l,m,2*rt);
        else update(p,val,m+1,r,2*rt+1);
     
        Seg[rt] = max(Seg[2*rt],Seg[2*rt+1]);
    }
     
    void get(int l,int r,int rt)
    {
        if(l==r)
        {
            POS=l;
            return ;
        }
     
        int m=(l+r)/2;
     
        if(Seg[2*rt]>Seg[2*rt+1]) get(l,m,2*rt);
        else get(m+1,r,2*rt+1);
    }
     
    int main()
    {
        while(~scanf("%d%d",&n,&m))
        {
            for(int i=1;i<=n;i++) scanf("%d",&a[i]);
     
            for(int i=0;i<=100000;i++) p[i]=n+1;
            for(int i=n;i>=1;i--) nx[i] = p[a[i]], p[a[i]]=i;
     
            memset(In,0,sizeof In);
            memset(Seg,0,sizeof Seg);
            memset(sx,0,sizeof sx);
            memset(A,0,sizeof A);
     
            int sz=0;
     
            for(int i=1;i<=n;i++)
            {
                if(In[a[i]])
                {
                    update(a[i],nx[i],0,100000,1);
                    continue;
                }
                if(sz<m)
                {
                    sz++;
                    A[sz]=a[i]; sx[a[i]]=sz;
                    update(a[i],nx[i],0,100000,1);
                }
     
                else
                {
                    get(0,100000,1);
                    update(POS,0,0,100000,1);
     
                    int t = sx[POS]; sx[POS]=0; In[POS]=0;
     
                    update(a[i],nx[i],0,100000,1);
                    sx[a[i]]=t; A[t]=a[i];
                }
     
                In[a[i]]=1;
            }
     
            for(int i=1;i<=sz;i++)
            {
                printf("%d",A[i]);
                if(i<sz) printf(" ");
                else printf("
    ");
            }
        }
        return 0;
    }
  • 相关阅读:
    googleMapReduce
    leveldb0
    大端模式和小端模式
    信号
    js中判断对象类型的几种方法
    js DOM之基础详解
    JavaScript作用域与闭包总结
    SCRIPT438: 对象不支持“trim”属性或方法
    JS合并多个数组去重算法
    js的 break 和 continue 计算问题
  • 原文地址:https://www.cnblogs.com/zufezzt/p/6601478.html
Copyright © 2020-2023  润新知