HDU 5400 Arithmetic Sequence(数学)——多校练习9

Arithmetic Sequence

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


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
 
/*********************************************************************/

题意:给你一个序列b1,b2,⋯,bn,问有多少个区间[l,r]满足该区间存在一个i,使得[l,i]是以d1为公差的等差数列,[i,r]是以d2为公差的等差数列

解题思路:老办法,观察样例吧,第一个样例的取法是{0},{0,2},{0,2,0},{0,2,0,-2},{2},{2,0},{2,0,-2},{0},{0,-2},{-2},{-2,0},{0}共12种

由此可见我们只需先找出满足题意的区间[l,r],知道里面序列的个数k,那么该区间的情况数为


但是有一点不能忽略,即一个元素bi,若它既属于前一个区间,又属于后一个区间的话,它本身会被多计算一次,比如样例1中的-2,它既属于区间[1,4],又属于区间[4,5],那么若单纯带公式再相加,那么取法{-2}会被计算两次,所以解题的时候判断一下,减去多算的即为结果。

放上一组样例以供参考

Input

5 2 2
0 2 0 2 4

Output

9

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<stdlib.h>
#include<cmath>
#include<string>
#include<algorithm>
#include<iostream>
#define exp 1e-10
using namespace std;
const int N = 100005;
const int inf = 1000000000;
const int mod = 258280327;
int s[N];
int main()
{
    int n,d1,d2,i,t,j,sum;
    __int64 ans,k;
    while(~scanf("%d%d%d",&n,&d1,&d2))
    {
        t=1;sum=j=0;k=1;ans=0;
        for(i=1;i<=n;i++)
            scanf("%d",&s[i]);
        for(i=1;i<n;i++)
        {
            if(t)
            {
                if(s[i]+d1==s[i+1])
                    k++;
                else
                    t=0;
                j=0;
            }
            if(!t)
            {
                if(s[i]+d2==s[i+1])
                {
                    k++;
                    j++;
                }
                else
                {
                    ans+=(k+1)*k/2;
                    if(sum+k>i)
                        ans--;
                    //printf("%d\n",k);
                    k=1;
                    t=1;
                    sum=i;
                    if(j)
                        i--;
                }
            }
        }
        ans+=(k+1)*k/2;
        if(sum+k>i)
            ans--;
        //printf("%d\n",k);
        printf("%I64d\n",ans);
    }
    return 0;
}
菜鸟成长记


你可能感兴趣的:(数学,ACM)