CF1992G 题解
纪念一下独立做出来的 *2000。
题意简述
给你一个集合 ,其中的元素为 ,定义 为集合 中从小到大不存在的第 个正整数。
求 。
解法
考虑枚举 ,再计算有多少个 符合 。
我们分为两种情况:
-
,此时 中的元素可能小于 ,也可能大于 。
-
,此时 中的元素小于 。
先考虑第一种情况。
既然是明摆着让 过,不如往 方面想想。
我们枚举 的同时枚举 中小于 的数的个数,记为 ,设 中大于 的数的个数为 ,则根据定义可以推导出 。
相当于在小于 的 个数中选择 个,在大于 的 个数中选择 个,显然有 种情况,对应到答案的贡献就是 。
再考虑第二种情况。
也是枚举 。设 为选择了多少个数(因为 ,所有的数小于等于 ,所以讨论 与 的大小关系没意义),则容易发现,当且仅当 时满足条件。
于是预处理组合数就可以在 的时间内回答一个测试点。
Code
#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int,int> pii;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
const int N=5e3+10,INF=0x3f3f3f3f3f3f3f3f,mod=1e9+7;
int jc[N],jcinv[N];
int qpow(int a,int p){
int ans=1;
while(p){
if(p&1)ans=ans*a%mod;
a=a*a%mod;
p>>=1;
}
return ans;
}
void init(){
jc[0]=jcinv[0]=1;
for(int i=1;i<N;i++){
jc[i]=jc[i-1]*i%mod;
jcinv[i]=qpow(jc[i],mod-2);
}
}
int C(int n,int m){return jc[n]*jcinv[n-m]%mod*jcinv[m]%mod;}
void solve(){
int n,ans=0;
cin>>n;
for(int a=1;a<=n;a++){
for(int x=0;x<=a-1;x++){
int y=a-1-2*x;
if(y<0)break;
if(n-a>=y)ans=(ans+C(a-1,x)*C(n-a,y)%mod*a%mod)%mod;
}
}
for(int a=n+1;a<=n+n+1;a++){
if(a%2==1)ans=(ans+C(n,a/2)*a%mod)%mod;
}
cout<<ans<<'\n';
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
init();
int t;cin>>t;
while(t--)solve();
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】