时间限制: 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 ",m); return 0; }