codeforces 466d Increase Sequence
1 second
256 megabytes
standard input
standard output
Peter has a sequence of integers a1, a2, ..., an. Peter wants all numbers in the sequence to equal h. He can perform the operation of "adding one on the segment [l, r]": add one to all elements of the sequence with indices from l to r (inclusive). At that, Peter never chooses any element as the beginning of the segment twice. Similarly, Peter never chooses any element as the end of the segment twice. In other words, for any two segments [l1, r1] and [l2, r2], where Peter added one, the following inequalities hold: l1 ≠ l2 and r1 ≠ r2.
How many distinct ways are there to make all numbers in the sequence equal h? Print this number of ways modulo 1000000007 (109 + 7). Two ways are considered distinct if one of them has a segment that isn't in the other way.
The first line contains two integers n, h (1 ≤ n, h ≤ 2000). The next line contains n integers a1, a2, ..., an (0 ≤ ai ≤ 2000).
Print a single integer — the answer to the problem modulo 1000000007 (109 + 7).
3 2
1 1 1
4
5 1
1 1 1 1 1
1
4 3
3 2 1 1
0
题意:给出一个序列,可以对其进行以下操作,取一段长度,从l到r,将其中的数全部加一。操作的次数不限,但对于两个操作,要求l1!=l2 && r1!=r2。求共有几种操作集合,使得整个序列的值最后都等于h。
思路:想了好久还是想不出来,最后看的题解。反着来做,先将所有a[i]=h-a[i]。当然,为了后面方便计算,我们将边界条件a[0]=0,a[n+1]=0。由于操作中的限制(l1!=l2 && r1!=r2),所以我们很容易得出有解的情况是当且仅当-1<=a[i]-a[i-1]<=1。我们用变量cnt记录当前有多少个左端点l没有和右端点r配对。下面分类讨论:
1,a[i]-a[i-1]==1,此时i点上必定有一个左端点,所以cnt++,i-1点上没有右端点,所以不对ans进行操作。
2,a[i]==a[i-1],此时有两种情况,要嘛i点没有左端点,i-1点没有右端点,要嘛i点有左端点,i-1点有右端点。此时,第一种情况是cnt=0,第二种情况时,cnt++,ans×=cnt,cnt--。所以两种情况都可以用ans×=(cnt+1)来表示。
3,a[i]-a[i-1]=-1,此时i点没有左端点,i-1点必定有右端点,此时ans×=cnt,cnt--;
细节:因为我们统计右端点的情况是统计前一个的,所以循环的时候必须做到n+1位。
下面是代码
/*
* Author: Joshua
* Created Time: 2014年09月19日 星期五 20时36分35秒
* File Name: d.cpp
*/
#include<cstdio>
#include<iostream>
using namespace std;
#define maxn 2002
typedef long long LL;
int a[maxn],b[maxn],n,h; void solve()
{
int x;
for (int i=1;i<=n;++i)
{
scanf("%d",&x);
a[i]=h-x;
}
a[0]=0;a[n+1]=0;
for (int i=1;i<=n+1;++i)
{
b[i]=a[i]-a[i-1];
if (b[i]>1 || b[i]<-1)
{
printf("0\n");
return;
}
}
LL ans=1;
int mod = int (1e9+7),cnt=0;
for (int i=1;i<=n+1;++i)
{
if (b[i]==1)
{
cnt++;
continue;
}
if (b[i]==0) ans*=(cnt+1);
else ans*=(cnt--);
ans %=mod;
}
cout<<ans<<endl;
} int main()
{
while (scanf("%d%d",&n,&h)>0)
solve();
return 0;
}
改进:我们知道,当a[i]-a[i-1]==1的时候,cnt++,当a[i]-a[i-1]==-1的时候,cnt--,那么我们是不是就可以用a[i]来表示cnt呢,答案是可以。这样可以进一步降低时间复杂度,代码也更短,下面是改进后的代码。
/*
* Author: Joshua
* Created Time: 2014年09月19日 星期五 20时36分35秒
* File Name: d.cpp
*/
#include<cstdio>
#include<iostream>
using namespace std;
#define maxn 2002
typedef long long LL;
int a[maxn],b[maxn],n,h; void solve()
{
int x;
for (int i=1;i<=n;++i)
{
scanf("%d",&x);
a[i]=h-x;
}
a[0]=0;a[n+1]=0;
for (int i=1;i<=n+1;++i)
{
b[i]=a[i]-a[i-1];
if (b[i]>1 || b[i]<-1)
{
printf("0\n");
return;
}
}
LL ans=1;
int mod = int (1e9+7);
for (int i=1;i<=n+1;++i)
{
if (b[i]==1) continue;
if (b[i]==0) ans*=a[i]+1;
else ans*=a[i-1];
ans %=mod;
}
cout<<ans<<endl;
} int main()
{
while (scanf("%d%d",&n,&h)>0)
solve();
return 0;
}
codeforces 466d Increase Sequence的更多相关文章
- Codeforces 601B. Lipshitz Sequence(单调栈)
Codeforces 601B. Lipshitz Sequence 题意:,q个询问,每次询问给出l,r,求a数组[l,r]中所有子区间的L值的和. 思路:首先要观察到,斜率最大值只会出现在相邻两点 ...
- 【codeforces 466D】Increase Sequence
[题目链接]:http://codeforces.com/problemset/problem/466/D [题意] 给你n个数字; 让你选择若干个区间; 且这些区间[li,ri]; 左端点不能一样; ...
- Codeforces 626A Robot Sequence(模拟)
A. Robot Sequence time limit per test:2 seconds memory limit per test:256 megabytes input:standard i ...
- Curious Array Codeforces - 407C(高阶差分(?)) || sequence
https://codeforces.com/problemset/problem/407/C (自用,勿看) 手模一下找一找规律,可以发现,对于一个修改(l,r,k),相当于在[l,r]内各位分别加 ...
- codeforces 622A Infinite Sequence
A. Infinite Sequence time limit per test 1 second memory limit per test 256 megabytes input standard ...
- Codeforces 626A Robot Sequence
A. Robot Sequence time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...
- CodeForces 623E Transforming Sequence 动态规划 倍增 多项式 FFT 组合数学
原文链接http://www.cnblogs.com/zhouzhendong/p/8848990.html 题目传送门 - CodeForces 623E 题意 给定$n,k$. 让你构造序列$a( ...
- CodeForces 601B Lipshitz Sequence
Lipshitz Sequence 题解: 可以通过观察得到,对于任意一个区间来说, 只有相邻的2个点的差值才会是区间的最大值. 具体观察方法,可以用数学分析, 我是通过画图得到的. 那么基于上面的观 ...
- CF思维联系–CodeForces -224C - Bracket Sequence
ACM思维题训练集合 A bracket sequence is a string, containing only characters "(", ")", ...
随机推荐
- 51nod_1298:圆与三角形(计算几何)
题目链接 判断圆和三角形是否相交 可以转化为 判断三条线段是否和圆相交 #include<iostream> #include<cstdio> #include< ...
- spark-2.2.0安装和部署——Spark集群学习日记
前言 在安装后hadoop之后,接下来需要安装的就是Spark. scala-2.11.7下载与安装 具体步骤参见上一篇博文 Spark下载 为了方便,我直接是进入到了/usr/local文件夹下面进 ...
- mysql内部级联删除
1,创建user表 属性:id,name 2,创建userInfo表 属性:id,age 在userInfo表中创建外键id,如下图: 在user表中插入两个用户信息 (1,'1'),(2,'2') ...
- (转)JAVA堆栈操作
java.util.Queue用法(是util中的一个接口) 队列是一种特殊的线性表,它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作.进行插入操作的端称为队尾,进行 ...
- [javascript] postmessage
摘要 postmessage 作为 html5 跨域传值的解决方法,灰常好用啊..本次用的是页面a 用iframe 嵌入 页面b. 使用方法 postmessage 参数 otherWindow.po ...
- 转载:vs2010 问题 >LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
原文链接:http://www.cnblogs.com/newpanderking/articles/3372969.html >LINK : fatal error LNK1123: 转换到 ...
- 开源蜘蛛集合(转自haizhiguang博客,链接:http://blog.csdn.net/haizhiguang/article/details/20209573)
各种蜘蛛: Heritrix 点击次数:1458 Heritrix是一个开源,可扩展的web爬虫项目.Heritrix设计成严格按照robots.txt文件的排除指示和META robots标签. ...
- HDU--1195--bfs--Open the Lock
/* Name: HDU--1195--Open the Lock Author: shen_渊 Date: 17/04/17 08:54 Description: bfs,用四维数组标记状态,每位数 ...
- JAVA中extends 与implements的用法
1. 在类的声明中,通过关键字extends来创建一个类的子类.一个类通过关键字implements声明自己使用一个或者多个接口.extends 是继承某个类, 继承之后可以使用父类的方法, 也可以重 ...
- kickstart文件详解
kickstart自动应答文件选项非常多,以下只说明CentOS 6下几个常用的可能用到的选项.另外,CentOS 6和CentOS 7的选项有不小区别,所以请注意使用,可以查看官方安装文档. Cen ...