HDOJ 5400 Arithmetic Sequence 暴力枚举



Arithmetic Sequence

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


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
 

Author
xudyh
 

Source
 



/* ***********************************************
Author        :CKboss
Created Time  :2015年08月18日 星期二 12时21分22秒
File Name     :1005.cpp
************************************************ */

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <queue>
#include <set>
#include <map>

using namespace std;

typedef pair<int,int> pII;
typedef long long int LL;
const int maxn=100100;
const int INF=0x3f3f3f3f;

int n,d1,d2;
int a[maxn];
LL ans;

vector<pII> up,down;

void bd2()
{        
    LL aaa=n-1;
    for(int i=0,sz=up.size();i<sz;i++)
    {
        pII pi=up[i];
        LL dur=pi.second-pi.first+1;
        aaa+=dur*(dur-1)/2;
    }
    cout<<aaa<<endl;
}

int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);

    while(scanf("%d%d%d",&n,&d1,&d2)!=EOF)
    {
        ans=n;
        up.clear(); down.clear();
        /// one duan
        int left=-1,right=-1;
        int Left=-1,Right=-1;
        bool cl=false;
        bool Cl=false;

        for(int i=1;i<=n;i++) 
            scanf("%d",a+i);

        a[n+1]=INF; n++;

        for(int i=1;i<=n;i++) 
        {
            if(i>1)
            {
                int ca=a[i]-a[i-1];
                if(ca==d1)
                {
                    if(left==-1) 
                    {
                        left=i-1; right=i; cl=true;
                    }
                    else right=i;
                }
                else
                {
                    if(cl==true)
                    {
                        up.push_back(make_pair(left,right));
                        left=right=-1;
                        cl=false;
                    }
                }
            }
            if(i>1)
            {
                int ca=a[i]-a[i-1];
                if(ca==d2)
                {
                    if(Left==-1)
                    {
                        Left=i-1; Right=i; Cl=true;
                    }
                    else Right=i;
                }
                else
                {
                    if(Cl==true)
                    {
                        down.push_back(make_pair(Left,Right));
                        Left=Right=-1;
                        Cl=false;
                    }
                }
            }
        }

        if(d1==d2)
        {
            bd2();
            continue;
        }


        /// single duan
        for(int i=0,sz=up.size();i<sz;i++)
        {
            pII pi=up[i];
            LL dur=pi.second-pi.first+1;
            ans+=dur*(dur-1)/2;
        }
        for(int i=0,sz=down.size();i<sz;i++)
        {
            pII pi=down[i];
            LL dur=pi.second-pi.first+1;
            ans+=dur*(dur-1)/2;
        }

        /// double duan
        for(int i=0,j=0,sz1=up.size(),sz2=down.size();i<sz1&&j<sz2;)
        {
            if(up[i].second==down[j].first)
            {
                LL duan1=up[i].second-up[i].first;
                LL duan2=down[j].second-down[j].first;
                ans+=duan1*duan2;
                i++; j++;
            }
            else
            {
                if(up[i].second>down[j].first) j++;
				else if(up[i].second<down[j].first) i++;
            }
        }
		printf("%lld\n",ans);
    }
    
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值