Link with EQ 题解(dp)

题目链接

题目思路

这个(dp)有点巧妙

(dp[i][1])表示i个空位有一段被占领最终能有多少个人
(dp[i][2])表示i个空位有两端被占领最终能有多少个人

然后枚举端点,前缀和即可

代码

#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
",ans);
    }
    return 0;
}
不摆烂了,写题
原文地址:https://www.cnblogs.com/hunxuewangzi/p/15125446.html