题目:https://loj.ac/problem/6432
如果不选自己,设自己的值是 x ,需要让 “ a<x && 2*a>=x ” 的非 x 的值不被选;如果选自己,需要让 “ a>=x && 2*a<x ” 的非 x 的值被选。
注意是 “非 x ” 的值。
#include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; int rdn() { int ret=0;bool fx=1;char ch=getchar(); while(ch>'9'||ch<'0'){if(ch=='-')fx=0;ch=getchar();} while(ch>='0'&&ch<='9')ret=ret*10+ch-'0',ch=getchar(); return fx?ret:-ret; } const int N=1e5+5,mod=998244353; int upt(int x){while(x>=mod)x-=mod;while(x<0)x+=mod;return x;} int pw(int x,int k) {int ret=1;while(k){if(k&1)ret=(ll)ret*x%mod;x=(ll)x*x%mod;k>>=1;}return ret;} int n,k,a[N],b[N],jc[N],jcn[N]; bool cmp(int a,int b){return a>b;} void init() { jc[0]=1;for(int i=1;i<=n;i++)jc[i]=(ll)jc[i-1]*i%mod; jcn[n]=pw(jc[n],mod-2); for(int i=n-1;i>=0;i--)jcn[i]=(ll)jcn[i+1]*(i+1)%mod; } int C(int n,int m) { if(n<m)return 0; return (ll)jc[n]*jcn[m]%mod*jcn[n-m]%mod; } int cal(int x)//a<x&&2*a>=x { int l=1,r=n,L=n+1; while(l<=r) { int mid=l+r>>1; if(b[mid]>=x)l=mid+1; else if(2*b[mid]<x)r=mid-1; else L=mid,r=mid-1; } l=1; r=n; int R=0; while(l<=r) { int mid=l+r>>1; if(b[mid]>=x)l=mid+1; else if(2*b[mid]<x)r=mid-1; else R=mid,l=mid+1; } if(L<=R) return R-L+1; return 0; } int cal2(int x)//a>=x&&a<2*x { int l=1,r=n,x2=2*x,L=n+1; while(l<=r) { int mid=l+r>>1; if(b[mid]<x)r=mid-1; else if(b[mid]>=x2)l=mid+1; else L=mid,r=mid-1; } l=1; r=n; int R=0; while(l<=r) { int mid=l+r>>1; if(b[mid]<x)r=mid-1; else if(b[mid]>=x2)l=mid+1; else R=mid,l=mid+1; } if(x<x2)R--;//self if(L<=R) return R-L+1; return 0; } int main() { n=rdn();k=rdn(); for(int i=1;i<=n;i++) a[i]=b[i]=rdn(); sort(b+1,b+n+1,cmp); init(); for(int i=1;i<=n;i++) { int ct=cal(a[i]),ans=0; ans=C(n-ct-1,k); ct=cal2(a[i]); if(ct<k)ans=upt(ans+C(n-ct-1,k-ct-1)); printf("%d ",ans); } return 0; }