Arithmetic Sequence
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 424 Accepted Submission(s): 214
Problem Description
A sequence
b1,b2,⋯,bn
are called
(d1,d2)
-arithmetic sequence if and only if there exist
i(1≤i≤n)
such that for every
j(1≤j<i),bj+1=bj+d1
and for every
j(i≤j<n),bj+1=bj+d2
.
Teacher Mai has a sequence a1,a2,⋯,an . He wants to know how many intervals [l,r](1≤l≤r≤n) there are that al,al+1,⋯,ar are (d1,d2) -arithmetic sequence.
Teacher Mai has a sequence a1,a2,⋯,an . He wants to know how many intervals [l,r](1≤l≤r≤n) there are that al,al+1,⋯,ar are (d1,d2) -arithmetic sequence.
Input
There are multiple test cases.
For each test case, the first line contains three numbers n,d1,d2(1≤n≤105,|d1|,|d2|≤1000) , the next line contains n integers a1,a2,⋯,an(|ai|≤109) .
For each test case, the first line contains three numbers n,d1,d2(1≤n≤105,|d1|,|d2|≤1000) , the next line contains n integers a1,a2,⋯,an(|ai|≤109) .
Output
For each test case, print the answer.
Sample Input
5 2 -2 0 2 0 -2 0 5 2 3 2 3 3 3 3
Sample Output
12 5
Author
xudyh
Source
题目传送门:
HDU 5400
这道题目其实很简单。用一个循环就可以做。不过开始想的有点复杂了。题目的意思就是给你一个序列,并且给你两个数字,d1和d2。让你从序列中找有多少个区间符合条件,条件是存在一个i使得1<=j<i,满足aj+1=aj+d1,并且i<=j<n,满足aj+1=aj+d2。也就是说存在一个断点,使得断点前的序列公差为d1,断点后的序列公差为d2。
需要注意的是,存在特殊情况,每个数字本身都是一种情况,也就是a0。
还有就是,存在公差全部为d1或者全部为d2的。
但是不存在先d2后d1的情况。所以,我们要找的就是,先出现d1后出现d2。只要找到第一个出现d2之后的不是d2的情况,然后把断点加到这里就可以了。
拿题目里给的例子来说,拿第一个例子来讲,
0 2 0 -2 0
它们的差值是 2 -2 -2 2 找到第一个出现在-2之后的2,也就是第四个数字。所以说前三个数字就是一种排列情况。2 -2 -2。一共有几种情况?就是3+2+1=6。
具体来说就是(2),(-2),(-2),(2,-2),(-2,-2),(2,-2,-2)。所以只要找到断点之后,把前面累加的情况再递减累加然后加到ans中就可以了。
然后再从断点处继续向下计算下一种序列情况就可以了。
代码:
#include <cstdio>
#include <iostream>
#define N 100010
int a[N];
int c[N];
using namespace std;
int main()
{
int n,d1,d2;
int flag; //用来标记出现的是d1还是d2
long long ans,sum;
while(~scanf("%d%d%d",&n,&d1,&d2))
{
flag=0;
ans=0;
sum=0;
scanf("%d",&a[0]);
for(int i=1;i<n;i++)
{
scanf("%d",&a[i]);
c[i-1]=a[i]-a[i-1];
}
for(int i=0;i<n-1;i++)
{
if(flag==0)
{
if(c[i]==d1)
sum++;
else if(c[i]==d2)
{
flag=1;
sum++;
continue;
}
else
{
while(sum)
{
ans+=sum;
sum--;
}
sum=0;
}
}
if(flag==1)
{
if(c[i]==d2)
sum++;
else
{
while(sum)
{
ans+=sum;
sum--;
}
sum=0;
flag=0;
i--;
}
}
}
while(sum)
{
ans+=sum;
sum--;
}
printf("%lld\n",ans+n);
}
return 0;
}