您的位置:首页 > 大数据 > 人工智能

2015 Multi-University Training Contest 9 1005

2015-08-20 00:02 393 查看

Arithmetic Sequence

Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 779 Accepted Submission(s): 349


[align=left]Problem Description[/align]
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+d1and 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.

[align=left]Input[/align]
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).

[align=left]Output[/align]
For each test case, print the answer.

[align=left]Sample Input[/align]

5
2 -2

0 2 0 -2 0

5 2
3
2 3 3 3 3

[align=left]Sample Output[/align]

12
5

[align=left]Author[/align]
xudyh

[align=left]Source[/align]
2015 Multi-University Training Contest 9

题意:求在区间[1,N]中,[l,r]区间满足 l<=j<i && i<=j<r 中前半段为公差为d1的等差数列,后半段为d2的等差数列的区间个数。
分析:
首先预处理出来出 i 这个位置向前d1​​的等差序列和向后d22​​的等差数列能延续到多长,记作 l[i], r[i]

如果d1≠d2,那么枚举中间位置,答案为l[i]*r[i]

如果d1=d​​2,枚举开始位置,答案为ri

其实我一开始也没看懂,不理解为什么单个数也能成为的区间也成立,后来无情打脸说离散没学好,说是数理逻辑中有当条件为假命题时,不论结果是真命题还是假命题,整个命题都是真命题,也算一个很牵强的解释吧= =

d1!=d2,l[i]*r[i]可以说左边有l[i]个区间符合条件,右边有r[i]个区间符合条件,然后相乘得到组合起来有多少区间

d1==d2,l[i]可以理解成 i 左边有多少符合条件的区间。

#pragma comprint(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<string>
#include<iostream>
#include<cstring>
#include<cmath>
#include<stack>
#include<queue>
#include<vector>
#include<map>
#include<stdlib.h>
#include<time.h>
#include<algorithm>
#define LL __int64
#define FIN freopen("in.txt","r",stdin)
using namespace std;
const int MAXN=100000+5;
int n,d1,d2;
int l[MAXN],r[MAXN],a[MAXN];
int main()
{
while(scanf("%d %d %d",&n,&d1,&d2)!=EOF)
{
for(int i=1;i<=n;i++) l[i]=r[i]=1;
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=2;i<=n;i++)
if(a[i]-a[i-1]==d1)
l[i]=l[i-1]+1;
for(int i=n-1;i>=1;i--)
if(a[i+1]-a[i]==d2)
r[i]=r[i+1]+1;
LL ans=0;
if(d1!=d2)
{
for(int i=1;i<=n;i++)
ans+=(LL)l[i]*r[i];
}
else
{
for(int i=1;i<=n;i++)
ans+=l[i];
}
printf("%I64d\n",ans);
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: