2015 Multi-University Training Contest 9 1005
Arithmetic Sequence
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 779 Accepted Submission(s): 349
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+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.
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
题意:求在区间[1,N]中,[l,r]区间满足 l<=j<i && i<=j<r 中前半段为公差为d1的等差数列,后半段为d2的等差数列的区间个数。
分析:
View Code
首先预处理出来出 i 这个位置向前d1的等差序列和向后d22的等差数列能延续到多长,记作 l[i], r[i]
如果d1≠d2,那么枚举中间位置,答案为l[i]*r[i]
如果d1=d2,枚举开始位置,答案为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; }