ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

AGC049D - Convex Sequence

2020-11-17 08:00:49  阅读:313  来源: 互联网

标签:数列 Sequence int ll AGC049D Convex include mo define


询问满足如下条件的数列的方案数:

\(a_i\ge 0\)

\(\sum a_i=m\)

\(2a_i\le a_{i-1}+a_{i+2}\)

\(n,m\le 10^5\)


自己搞的时候连负数都不知道怎么处理……

钦定最终数列的最小值(位置为第二关键字)。设为\(i\)。

那么一个合法的数列可以如此构造:

  1. 整个数列加\(1\)。
  2. 选择\(j<i\),给\(a_{j},a_{j-1},a_{j-2},\dots,a_1\)分别加\(1,2,3,\dots\)。至少给\(i-1\)操作一次。
  3. 选择\(j>i\),给\(a_j,a_{j+1},a_{j+2},\dots,a_{n}\)分别加\(1,2,3,\dots\)。

无序的搞上面的若干次操作,最终要求总和为\(m\)。

不关心具体取值,于是可以看成背包。物品大小平方级增长,所以有效的物品数可视作\(\sqrt m\)。\(i\)固定时直接做是\(m\sqrt m\)的,移动\(i\)时相当于删物品和加物品。都可以\(O(m)\)做,总时间\(O(m\sqrt m)\)


using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 100005
#define ll long long
#define mo 1000000007
int n,m;
int f[N];
void insert(int f[],ll w){
	for (ll i=w;i<=m;++i)
		f[i]=(f[i]+f[i-w])%mo;
}
void erase(int f[],ll w){
	for (ll i=m;i>=w;--i)
		f[i]=(f[i]-f[i-w]+mo)%mo;
}
int query(ll x){
	return x<0 || x>m?0:f[x];
}
ll val(int x){return (ll)x*(x+1)/2;}
int main(){
	freopen("in.txt","r",stdin);
	scanf("%d%d",&n,&m);
	f[0]=1;
	insert(f,n);
	for (int i=1;i<=n-1;++i)
		insert(f,val(i));
	ll ans=0;
	for (int i=1;i<=n;++i){
		ans+=query(m-val(i-1));
		erase(f,val(n-i));
		insert(f,val(i));			
	}
	ans%=mo;
	printf("%lld\n",ans);
	return 0;
}

标签:数列,Sequence,int,ll,AGC049D,Convex,include,mo,define
来源: https://www.cnblogs.com/jz-597/p/13992257.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有