codevs 1979 第K个数

 时间限制: 1 s
 空间限制: 1000 KB
 题目等级 : 黄金 Gold
题目描述 Description

给定一个长度为N(0<n<=10000)的序列,保证每一个序列中的数字a[i]是小于maxlongint的非负整数 ,编程要求求出整个序列中第k大的数字减去第k小的数字的值m,并判断m是否为质数。(0<k<=n)

输入描述 Input Description

第一行为2个数n,k(含义如上题)
第二行为n个数,表示这个序列

输出描述 Output Description

如果m为质数则
第一行为'YES'(没有引号)
第二行为这个数m
否则 
第一行为'NO'
第二行为这个数m

样例输入 Sample Input
5 2
1 2 3 4 5
样例输出 Sample Output
YES
2
数据范围及提示 Data Size & Hint

20%数据满足0<n<=10
50%数据满足0<n<=5000
100%数据满足0<n<=10000

 

splay查询第K大值和第K小值

坑点:差值可能小于0 

素数在自然数范围内

屠龙宝刀点击就送

#include <ctype.h>
#include <cstdio>
#define N 20000
void read(long long &x)
{
    x=0;bool f=0;
    register char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=1;
    for(; isdigit(ch);ch=getchar()) x=(x<<3)+(x<<1)+ch-'0';
    x=f?(~x)+1:x;
}
long long root,cn,tim,siz[N],ch[N][2],fa[N],cnt[N];
long long data[N],n,k;
class type
{
    private:
        void pushup(long long rt)
        {
            long long l=ch[rt][0],r=ch[rt][1];
            siz[rt]=siz[l]+siz[r]+cnt[rt];
        }
    public:
        void ins(long long &rt,long long x)
        {
            if(rt==0)
            {
                rt=++tim;
                data[tim]=x;
                siz[tim]=cnt[tim]=1;
                return;
            }
            if(data[rt]==x)
            {
                siz[rt]++;
                cnt[rt]++;
                return;
            }
            if(x<data[rt])
            {
                ins(ch[rt][0],x);
                fa[ch[rt][0]]=rt;
                pushup(rt);
            }
            else
            {
                ins(ch[rt][1],x);
                fa[ch[rt][1]]=rt;
                pushup(rt);
            }
        }
        long long getkth(long long rt,long long k)
        {
            long long l=ch[rt][0];
            if(siz[l]+1<=k&&k<=siz[l]+cnt[rt]) return data[rt];
            if(k<siz[l]+1) return getkth(ch[rt][0],k);
            if(siz[l]+cnt[rt]<k) return getkth(ch[rt][1],k-(siz[l]+cnt[rt]));
        }
        bool pd(long long n)
        {
            if(n<0) return false;
            for(long long i=2;i*i<=n;i++)
            if(n%i==0) return false;
            return true;
        }
};
class type *s;
int main()
{
    read(n);read(k);
    for(long long a,i=1;i<=n;i++)
    {
        read(a);
        s->ins(root,a);
    }
    long long k_min=s->getkth(root,k),k_max=s->getkth(root,n-k+1),m=k_max-k_min;
    bool f=s->pd(m);
    f?puts("YES"):puts("NO");
    printf("%lld\n",m);
    return 0;
}

 

posted @ 2017-08-08 16:39  杀猪状元  阅读(166)  评论(0编辑  收藏  举报