2019 ICPC 上海網絡賽 D. Counting Sequences I

因爲最多就13個非1數字出現,所以枚舉2到3000,每個數字出現次數,中間的剪枝要注意的就是連乘之和不能大於6000,連乘之和已經大於6000或者還沒選數字但是當前能選最小數字的平方已經大於6000就返回
(int)pow(13,1)在我的codeblocks上居然是12,一直不知道錯哪裏,結果是精度原因。。。。。。。。

#include <bits/stdc++.h>
#define eps 1e-14
#define pi acos(-1)
#define ll long long
#define RD T*(rand()*2-RAND_MAX)
#define Drand (long double)rand()/RAND_MAX
#define LINF 0x7f7f7f7f7f7f7f7f
#define INF 0x3f3f3f3f
using namespace std;
const int maxn=5e5+50;
const long long mod=1e9+7;
ll MOD(ll a,ll m){return a>m?a%m+m:a;}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}

ll ans[3005],A[3005],INV[3005];


ll qpow(ll a, ll b)
{
    ll ans = 1;
    a = a % mod;
    while(b)
    {
        if(b&1) ans = ans * a % mod;
        a = a*a % mod;
        b >>= 1;
    }
    return ans;
}
int counts=0;
ll n=3000;
bool dfs(ll add,ll mul,ll x,ll sum,ll inv,int ff)
{
    if(x==n+1 || add<=mul &&  sum>=2 && ff==0)
    {
        if(ff==1)return true;
        ll num1=mul-add;
        ll cnt=sum+num1;
        if(cnt>n)return false;
        ans[cnt]=(ans[cnt]+A[cnt]*inv%mod*INV[num1]%mod)%mod;
//        if(cnt==3000){
//            cout<<" add = "<<add<<" mul = "<<mul<<" x = "<<x<<" sum = "<<sum<<" cnt = "<<cnt<<
//            " num1 = "<<num1<<" mid = "<<A[cnt]*inv%mod*INV[num1]%mod<<" inv = "<<inv<<endl;
//            cout<<ans[cnt]<<endl;
//        }
        ff=1;
        if(cnt==n)return true;
        else{
            cnt++;
            ll a=add+x-1;
            ll m=mul*(x-1);
            if(m>2*n || m-a>n-cnt)return true;
        }
        if(x==n+1)return true;
    }
    for(ll i=0;qpow(x,i)*mul<=2*n;i++){
        if(i!=0)ff=0;
//        cout<<x<<" "<<i<<"       "<<add<<" "<<mul<<" "<<qpow(x,i)<<endl;
        int flag=dfs(add+x*i,mul*qpow(x,i),x+1,sum+i,inv*INV[i]%mod,ff);
        if(flag==false)break;
    }
    return true;
}

int main()
{
//    freopen("in.txt", "r", stdin);
//    freopen("out.txt", "w", stdout);
    A[0] = 1;
    for(int i = 1; i <= 3000; i++) A[i] = A[i-1] * i % mod;
    for(int i = 0; i <= 3000; i++) INV[i] = qpow(A[i], mod-2);
    dfs(0,1,2,0,1,0);
    cout<<(int)pow(13,1)<<endl;
//    for(int i=2;i<=20;i++){
//        cout<<ans[i]<<endl;
//    }
    int t;
    scanf("%d",&t);
    while(t--){
        int n;
        scanf("%d",&n);
        printf("%lld\n",ans[n]);
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章