题解:P14636 [NOIP2025] 清仓甩卖 / sale(民间数据)
十二点多过了大样例。喜提后俩题加起来
感觉直接数不太好做,用
::::info[考场代码]
#include<bits/stdc++.h>
using namespace std;
namespace z {
const int N = 5e5 + 5, mod = 998244353;
#define int long long
int a[N],fac[N],inv[N],pw[N];
int qpow(int a, int b) {
int res = 1;
while(b) {
if(b & 1) res = res * a % mod;
a = a * a % mod;
b >>= 1;
}
return res;
}
int C(int n, int m){
if(n<0||m<0||n<m)return 0;
return fac[n]*inv[m]%mod*inv[n-m]%mod;
}
void main() {
fac[0]=pw[0]=inv[0]=1;
for(int i=1;i<N;i++)fac[i]=fac[i-1]*i%mod,pw[i]=pw[i-1]*2%mod,inv[i]=qpow(fac[i],mod-2);
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
freopen("sale.in","r",stdin);
freopen("sale.out","w",stdout);
int Cid, T;cin>>Cid>>T;
while(T--){
int n, m; cin >> n >> m;
for(int i = 1; i <= n; i++) cin >> a[i],a[i]*=2;
sort(a + 1, a + n + 1, greater<int>());
int ans = qpow(2, n);
for(int i = 1; i <= n; i++) {
int l=n+1;
for(int j = i+1;j<=n;j++) {
if(a[j]>a[i]/2) {
l=max(l,j+1);
while(l-1>j&&a[l-1]+a[j]<a[i])l--;
int rem=max(0ll,j-1-(i+1)+1);
int tmp=C(rem+i-1,m-2-i+1);
ans-=tmp*(pw[n-l+1]-(a[i]==a[j]))%mod;
}
}
}
cout << (ans%mod+mod)%mod << '\n';
}
}
#undef int
}
int main() {
z::main();
return 0;
}
::::