hdu 5400 Arithmetic Sequence(重构数组)

Arithmetic Sequence

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


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+d1  and 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

题意:求一个区间,使得区间内存在一点i,序列[l,i)是公差为d1的等差数列,序列[i,r]是公差为d2的等差数列,问你一共有几个区间满足

思路:枚举i点即可,但是直接枚举会有O(n²)的复杂度会炸掉,所以要用l和r数组分别记录当前点最大能延伸到前面和后面的距离,最后相乘即可,注意两点

1:当d1=d2的时候,区间会算重,此时只需要特判即可,值等于所有l或者所有r

2:l和r数组必须为long long 10^6*10^6会超出int型....因为这个WA了好多次。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define N 100010
#define LL long long
int a[N];
LL l[N],r[N];
int main()
{
    int n,d1,d2;
    while(~scanf("%d %d %d",&n,&d1,&d2))
    {
        long long ans=0;
        for(int i=1; i<=n; i++)
        {
            scanf("%d",&a[i]);
            l[i]=r[i]=1;
        }
        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;
        if(d1==d2)
        {
            for(int i=1; i<=n; i++)
                ans+=l[i];
        }
        else
        {
            for(int i=1; i<=n; i++)
                ans+=l[i]*r[i];
        }
        printf("%lld\n",ans);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值