• 杂题


    题意

    给定(n,m),初始序列({a_i})全为(0),可以进行任意次操作,选取一段长度为(m)的区间,依次赋值为(1,2,cdots ,m)
    求能得到多少种任意位置非(0)的序列
    (n,mle 10^6)

    做法

    感谢神仙MAOoo的耐心教导

    (f_i(j))为第(i)个位置,填(j),前(i)个位置不同的方案数
    考虑若目前所处的位置(le n-m+1),那么这个位置可以赋值为任意([1,m])的数:

    [egin{aligned} &ile n-m+1 egin{cases} f_i(1)=sumlimits_{k=1}^m f_{i-1}(k)\ f_i(j)=f_{i-1}(m)+f_{i-1}(j-1)(j eq 1) end{cases}\\ &i>n-m+1 egin{cases} f_i(j)=f_{i-1}(m)+f_i(j-1)(jge i-(n-m)) end{cases}\ end{aligned}]

    对于(ile n-m+1)
    观察到(f_i(j)-f_{i-1}(j-1)=f_{i-1}(m)(j eq 1))
    那么就是对于dp数组,滑动窗口,维护一个差值
    仅需求出(f_i(1))

    对于(i>n-m+1)类似

    这道题很难讲得很清楚,所以放份代码

    Code

    #include<bits/stdc++.h>
    typedef int LL;
    typedef double dl;
    #define opt operator
    #define pb push_back
    #define pii std::pair<LL,LL>
    const LL maxn=1e6+9,mod=1e9+7,inf=0x3f3f3f3f;
    LL Read(){
    	LL x(0),f(1); char c=getchar();
    	while(c<'0' || c>'9'){
    		if(c=='-') f=-1; c=getchar();
    	}
    	while(c>='0' && c<='9'){
    		x=(x<<3ll)+(x<<1ll)+c-'0'; c=getchar();
    	}return x*f;
    }
    void Chkmin(LL &x,LL y){
    	if(y<x) x=y;
    }
    void Chkmax(LL &x,LL y){
    	if(y>x) x=y;
    }
    LL add(LL x,LL y){
    	return x+=y,x>=mod?x-mod:x;
    }
    LL dec(LL x,LL y){
    	return x-=y,x<0?x+mod:x;
    }
    LL mul(LL x,LL y){
    	return 1ll*x*y%mod;
    }
    LL Pow(LL base,LL b){
    	LL ret(1); while(b){
    		if(b&1) ret=mul(ret,base); base=mul(base,base); b>>=1;
    	}return ret;
    }
    LL n,m;
    LL dp[maxn<<1];
    int main(){
    	LL n(Read()),m(Read());
    	LL l(1),r(m);
    	dp[r]=1;
    	LL delta(0),sum(1);
    	++l; ++r;
    	for(LL i=1;i<n;++i,++l,++r){
    		if(i+1<=n-m+1){
    			sum=dec(sum,dp[l-1]);
    			dp[r]=add(1ll*(m-2)*delta%mod,sum);
    		}
    		delta=add(delta,add(delta,dp[l-1]));
    		sum=add(sum,dp[r]);
    	}
    	printf("%d
    ",add(dp[l-1],delta));
    	return 0;
    }
    
  • 相关阅读:
    maven打包额外的资源文件
    阿里巴巴的程序员等级
    sql是最成功的第四代语言
    nginx的配置与应用
    浏览器的同源策略与跨域问题的解决方案
    算法:二分查找(基础)
    动态类型语言和静态类型语言
    【VS开发】单文档中往视图中加入控件
    【VS开发】使用VS2010创建MFC ActiveX工程项目
    【VS开发】使用VS2010创建MFC ActiveX工程项目
  • 原文地址:https://www.cnblogs.com/Grice/p/14284975.html
Copyright © 2020-2023  润新知