ARC 071 F Infinite Sequence - dp - 前缀和

题目大意:有多少个无限长的由{1,2,⋯,n}组成的序列a1,a2,…满足以下条件?
第n个及以后的元素是相同的,即若i,j≥n,ai=aj。
对于每个元素i,紧随第i个元素后的ai个元素是相同的,即若i<j<k≤i+ai,aj=ak。
题解:
显然如果某个数字a[i]=x>1,要么i+1到i+x全是1,要么从a[i+1]=y开始到结束全都是y。(换言之一个合法序列只要有两个相邻的大于1的数字那么这个序列就到此为止了)
那么枚举最后一个有这种效果的i,(即从a[i]>1且a[i+1]>1)或者不存在这种情况下的最后一个大于1的位置。记f[i]表示最后一个>1的数字是a[i],并且之前不存在两个相邻的数字>1。枚举上一个>1的数值(或者干脆i就是第一个),那么这个x只能放到一个前缀里面(或者干脆放不了),这个用一个前缀和优化前缀和优化dp即可。最后用f算答案。

#include<bits/stdc++.h>
#define gc getchar()
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define Rep(i,v) rep(i,0,(int)v.size()-1)
#define lint long long
#define mod 1000000007
#define db double
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define debug(x) cerr<<#x<<"="<<x
#define sp <<" "
#define ln <<endl
using namespace std;
typedef pair<int,int> pii;
typedef set<int>::iterator sit;
inline int inn()
{
    int x,ch;while((ch=gc)<'0'||ch>'9');
    x=ch^'0';while((ch=gc)>='0'&&ch<='9')
        x=(x<<1)+(x<<3)+(ch^'0');return x;
}
#define P(x) (x>=mod?x-=mod:0)
const int N=1000010;int f[N],s[N],ss[N];
int main()
{
    int n=inn(),ans=1,m=(n-1ll)*n%mod;
    rep(i,1,n) f[i]=(i>=3?ss[i-3]:0)+1,P(f[i]),s[i]=s[i-1]+f[i],P(s[i]),ss[i]=ss[i-1]+s[i],P(ss[i]);
    ans+=(n-1ll)*f[n]%mod,P(ans);rep(i,1,n-1) ans+=(lint)m*f[i]%mod,P(ans);return !printf("%d\n",ans);
}

猜你喜欢

转载自blog.csdn.net/Mys_C_K/article/details/83346390
今日推荐