2019 Shanghai Online Contest Problem D Counting Sequences I

本文深入解析了一道复杂的搜索思维题,通过使用C++语言实现,介绍了如何利用递归和组合数学的方法来解决这类问题。文章详细阐述了算法的实现过程,包括初始化阶乘数组、逆元数组,以及核心的搜索函数,最后通过输入测试用例验证了算法的正确性和效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

搜索思维题

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int Max=3000;
const ll M=1e9+7;
ll ANS[Max+10],JC[Max+10],INV[Max+10];
void F(int x,int mul,int sum,int num,ll inv){
    if(x==1){
        int xx=mul-sum;
        if(xx>=0&&num+xx<=Max){
            ANS[num+xx]=(ANS[num+xx]+JC[num+xx]*inv%M*INV[xx]%M)%M;
        }
        return;
    }
    F(x-1,mul,sum,num,inv);
    for(int i=1;mul*x<=Max*2;++i){
        mul=mul*x;
        F(x-1,mul,sum+x*i,num+i,INV[i]*inv%M);
    }
    return;
}
ll Pow(ll x,ll y){
    ll ans=1;
    for(;y;y/=2,x=x*x%M)if(y%2==1)ans=ans*x%M;
    return ans;
}
int main(){
    JC[0]=1;
    for(ll i=1;i<=Max;++i)JC[i]=JC[i-1]*i%M;
    for(ll i=0;i<=Max;++i)INV[i]=Pow(JC[i],M-2);
    F(Max,1,0,0,1);
    int T;cin>>T;while(T--){
        int x;
        cin>>x;
        cout<<ANS[x]<<endl;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值