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(1in) such that for every j(1j<i),bj+1=bj+d1and for every j(ij<n),bj+1=bj+d2.

Teacher Mai has a sequence a1,a2,,an. He wants to know how many intervals [l,r](1lrn) 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(1n105,|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的等差数列的区间个数。
分析:

首先预处理出来出 这个位置向前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

 

posted @ 2015-08-20 00:02  Cliff Chen  阅读(111)  评论(0编辑  收藏  举报