D. Increase Sequence
time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

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.

Input

The first line contains two integers n, h (1 ≤ n, h ≤ 2000). The next line contains n integers a1, a2, ..., an (0 ≤ ai ≤ 2000).

Output

Print a single integer — the answer to the problem modulo 1000000007 (109 + 7).

Sample test(s)
input
3 2
1 1 1
output
4
input
5 1
1 1 1 1 1
output
1
input
4 3
3 2 1 1
output
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的更多相关文章

  1. Codeforces 601B. Lipshitz Sequence(单调栈)

    Codeforces 601B. Lipshitz Sequence 题意:,q个询问,每次询问给出l,r,求a数组[l,r]中所有子区间的L值的和. 思路:首先要观察到,斜率最大值只会出现在相邻两点 ...

  2. 【codeforces 466D】Increase Sequence

    [题目链接]:http://codeforces.com/problemset/problem/466/D [题意] 给你n个数字; 让你选择若干个区间; 且这些区间[li,ri]; 左端点不能一样; ...

  3. Codeforces 626A Robot Sequence(模拟)

    A. Robot Sequence time limit per test:2 seconds memory limit per test:256 megabytes input:standard i ...

  4. Curious Array Codeforces - 407C(高阶差分(?)) || sequence

    https://codeforces.com/problemset/problem/407/C (自用,勿看) 手模一下找一找规律,可以发现,对于一个修改(l,r,k),相当于在[l,r]内各位分别加 ...

  5. codeforces 622A Infinite Sequence

    A. Infinite Sequence time limit per test 1 second memory limit per test 256 megabytes input standard ...

  6. Codeforces 626A Robot Sequence

    A. Robot Sequence time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...

  7. CodeForces 623E Transforming Sequence 动态规划 倍增 多项式 FFT 组合数学

    原文链接http://www.cnblogs.com/zhouzhendong/p/8848990.html 题目传送门 - CodeForces 623E 题意 给定$n,k$. 让你构造序列$a( ...

  8. CodeForces 601B Lipshitz Sequence

    Lipshitz Sequence 题解: 可以通过观察得到,对于任意一个区间来说, 只有相邻的2个点的差值才会是区间的最大值. 具体观察方法,可以用数学分析, 我是通过画图得到的. 那么基于上面的观 ...

  9. CF思维联系–CodeForces -224C - Bracket Sequence

    ACM思维题训练集合 A bracket sequence is a string, containing only characters "(", ")", ...

随机推荐

  1. OI内的排列与组合(简单版)

    §1基本原理 △让我们来看下面问题: 从甲地到乙地,可以乘火车,也可以乘汽车,还可以乘轮船.一天中,火车有4班,汽车有2班,轮船有3班.那么,一天中乘坐这些交通工具从甲地到乙地共有多少种不同走法?△分 ...

  2. python之基本内容

    这里提供在使用python进行开发中常使用到的方法技巧,如有不对欢迎批评指正. 要点:开发中类.变量特性查询,类型就是类,断言的使用,深浅复制判断等 python脚本文件是使用UTF-8编码的,所以在 ...

  3. mongodb3 ubuntu离线安装(非apt-get)及用户管理

    目前mongodb已经出到3.x,相对于2.x改动较大,本着学新不学旧的原则来捣鼓nosql数据库.最初想着apt-get安装但是软件源上都是2.x的,遂下载好后传到服务器安装. 1.下载 不得不说国 ...

  4. (转)每天一个linux命令(15):tail 命令

    场景:每次查看服务端的日志时候都需要反复重新加载服务端的日志.用tail命令可以很方便的查看服务器上的日志更新! tail 命令从指定点开始将文件写到标准输出.使用tail命令的-f选项可以方便的查阅 ...

  5. php+sqlserver实现分页效果

    找了一些实现的代码,都或多或少有点问题. 主要问题在于: 在进行一页数据查询时的sql语句格式问题, 开始尝试使用limit关键字查询,错误,limit用于mysql: 接着使用ROWNUM.row_ ...

  6. Apache Kafka - 介绍

    原文地址地址: http://blogxinxiucan.sh1.newtouch.com/2017/07/12/Apache-Kafka-介绍/ Apache Kafka教程 之 Apache Ka ...

  7. Hadoop(一)Centos7虚拟机网络配置

    Centos7虚拟机网络配置(桥接模式) 一 VirtualBox提供了三种工作模式,它们是bridged(桥接模式).NAT(网络地址转换模式)和host-only(主机模式). 1 桥接模式(br ...

  8. CentOS服务器运维监控Nagios(一)

    CentOS下搭建Nagios 王尚 2014.11.09 操作系统:CentOS-6.5-i386-bin-DVD1.iso 安装在VM中进行测试的. 本章需要的软件链接: php-5.3.2.ta ...

  9. Linux系统C语言socket tcp套接字编程

    1.套接字的地址结构: typedef uint32_t in_addr_t; //32位无符号整数,用于表示网络地址 struct in_addr{ in_addr_t s_addr; //32位 ...

  10. Http跨域时的Option请求

    写这篇文章时,我们碰到的一个场景是:要给R系统做一个扩展小应用,前端的html.js放在R系统里,后端需要做一个单独的站点N.B.com.这就导致了跨域问题,而且要命的是,后端同学没有权限向招聘的系统 ...