這個\(dp\)有點巧妙php
\(dp[i][1]\)表示i個空位有一段被佔領最終能有多少我的
\(dp[i][2]\)表示i個空位有兩端被佔領最終能有多少我的c++
而後枚舉端點,前綴和便可ide
#include<bits/stdc++.h> #define fi first #define se second #define debug cout<<"I AM HERE"<<endl; using namespace std; typedef long long ll; typedef pair<int,int> pii; const int maxn=1e6+5,inf=0x3f3f3f3f,mod=1e9+7; const double eps=1e-6; int n; ll dp[maxn][3]; ll pre[maxn]; ll qpow(ll a,ll b){ ll ans=1,base=a; while(b){ if(b&1) ans=ans*base%mod; base=base*base%mod; b=b>>1; } return ans; } signed main(){ // dp[i][1] 表示i個空位有一段被佔領 // dp[i][2] 表示i個空位有兩端被佔領 for(int i=2;i<=1e6;i++){ if(i>2){ dp[i][2]=(dp[i/2][2]+dp[i-i/2-1][2]+1)%mod; } dp[i][1]=dp[i-1][2]+1; pre[i]=(pre[i-1]+dp[i][1])%mod; } int _; scanf("%d",&_); while(_--){ scanf("%d",&n); ll ans=(2*pre[n-1]+n)*qpow(n,mod-2)%mod; printf("%lld\n",ans); } return 0; }