• Jzoj5450【NOIP2017提高A组冲刺11.4】Neutral


    你获得了无限个狗剩,为此你需要一个无限长的数组来存储狗剩,这个数组要满足以下条件
    1. 数组仅包含1, 2, 3, ..., n
    2. 如果n <= i, j,那么ai = aj
    3. 如果i < j < k <= i + ai,那么aj = ak

    数组还在生成中,反正现在很无聊,不如计算有多少种满足条件的数组?答案对1e9 + 7 取模

    看起来十分恐怖"无限长?!!"

    发现长度n后面没卵用

    嗯,让后还有一个限制?

    对,i~i+a[i]数字要求相同

    额,果断倒过来随便乱搞就做出来了

    设f[i]为做到倒数第i位的答案

    那么如果i填1,则有f[i]+=f[i-1]的转移

    如果第i位填k(k>1)那么就有f[i]+=f[i-k-1](相当于第i位后面跟了k个1)

    如果有连续两位不为i则整个数组都一定被确定下来(比如233333...或者是3444444.)

    所以就有f[i]+=(n-1)*(n-1)(第i有n-1种选法,i-1位也有n-1种,让后就全部确定)

    十分简单,大样例一次过,然而全场爆零?

    "

    100% 的数据满足1 <= n <= 10^6
    数据很有梯度(共100 个测试点,几乎是个等比数列,首项是4,公比大概是1.1)

    "

    然后OJ就爆炸了

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #define M 1000000007
    using namespace std;
    void ad(int& x,int y){ x=(x+y)%M; }
    int n,f[1000010],s[1000010];
    int main(){
    	freopen("neutral.in","r",stdin);
    	freopen("neutral.out","w",stdout);
    	scanf("%d",&n); 
    	f[0]=1; f[1]=n; s[1]=n; s[0]=0;
    	for(int i=2;i<=n;++i){
    		ad(f[i],f[i-1]);
    		ad(f[i],(n-1ll)*(n-1ll)%M);
    		ad(f[i],s[max(0,i-3)]+(n-1-max(0,i-3)));
    		s[i]=s[i-1]; ad(s[i],f[i]);
    	}
    	printf("%d
    ",f[n]);
    }

  • 相关阅读:
    文本检测和识别 代码结构梳理
    UnicodeDecodeError: 'utf-8' codec can't decode byte
    GPU 显存释放
    DCM 图片查看
    hive SQL 字母大小写转换
    vim常用命令之多行注释和多行删除
    js 模拟call、apply、bind实现
    CommonJS、AMD、CMD和ES6模块化区别
    js setTimeout setInterval 第三个参数说明
    js instanceof 实现原理
  • 原文地址:https://www.cnblogs.com/Extended-Ash/p/7800612.html
Copyright © 2020-2023  润新知