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(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.

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).

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

2015 Multi-University Training Contest 9

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

版权声明:来自: 码代码的猿猿的AC之路 http://blog.csdn.net/ck_boss

时间: 2024-11-20 04:50:56

HDOJ 5400 Arithmetic Sequence 暴力枚举的相关文章

hdu 5400 Arithmetic Sequence

click here~~ ***Arithmetic Sequence*** 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+d1 and for every j(i≤j<n),bj+1=bj+d2. Teacher Mai has a

hdu 5400 Arithmetic Sequence(模拟)

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+d1 and for every j(i≤j<n),bj+1=bj+d2. Teacher Mai has a sequence a1,a2,?,an. He wants to know h

HDU 5288 OO’s Sequence (暴力枚举因子)

题目链接:HDU 5288 OO's Sequence 题意:给出一个n,表示n个数的序列,函数f(l,r)定义,在l,r区间中存在多少个数,不能被其他数整除.求累加所有子区间的函数值 思路:从ai的小范围入手 1.a不能被b整除,即a的所有因子中不存在b,所以打表枚举所有的数的因子. 2.找到一个数(位置为i)满足条件时最左端l和最右端r,(i-l)*(r-i)就是对答案的贡献. AC代码: #include <stdio.h> #include <algorithm> #inc

HDU 5400 Arithmetic Sequence (2015年多校比赛第9场)

1.题目描述:点击打开链接 2.解题思路:本题利用扫描法解决.根据题意描述,[L,i)和[i,R)区间都构成了等差数列,因此可以实现用L[i],R[i]来维护从i开始向左向右可以延伸的最远长度,如果d1和d2不等,那么答案就是L[i]*R[i]求和,否则就是R[i]求和. 3.代码: //#pragma comment(linker, "/STACK:1024000000,1024000000") #include<iostream> #include<algorit

hdu(5400)——Arithmetic Sequence(想法题)

题意: 首先,现在给出三个数字n,d1,d2.然后第二行给出n个数字. 然后题目要求的是求这个序列中有几个区间满足一下条件之一: 1)这个区间是一个等差数列,且公差为d1或d2: 2)若一个区间为[l,r],那么有l<=i<=r,使得[l,i]范围内是公差为d1的等差数列,[i,r]区间内是公差为d2的等差数列. *注意,这里单个数字一定是满足等差数列的.而且这里数字最好都使用__int64来保存,因为这个原因我们队WA了好几次. 思路: 这里我设了头和尾两个指针,分别用l和r表示. 我用de

HZAU 21——Arithmetic Sequence——————【暴力 or dp】

Arithmetic Sequence Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 1810  Solved: 311[Submit][Status][Web Board] Description Giving a number sequence A with length n, you should choosing m numbers from A(ignore the order) which can form an arithmetic

hdoj 4932 Miaomiao&#39;s Geometry 【暴力枚举】

题意:在一条直线上有n个点,取一长度差为x的区间, 规定点必须是区间的端点, 让你找出来最大的x 策略:rt 分析可得:两个相邻点之间的区间要么是两个点的差,要么就是两个点的差的一半,那我们就简单枚举一下就好了 排好序之后再枚举 代码: #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #define M 200 using namespace std; do

hdoj 4932 Miaomiao&amp;#39;s Geometry 【暴力枚举】

题意:在一条直线上有n个点.取一长度差为x的区间. 规定点必须是区间的端点. 让你找出来最大的x 策略:rt 分析可得:两个相邻点之间的区间要么是两个点的差,要么就是两个点的差的一半,那我们就简单枚举一下就好了 排好序之后再枚举 代码: #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #define M 200 using namespace std; do

HDOJ 5305 Friends 暴力枚举

暴力枚举边的状态..... Friends Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 120    Accepted Submission(s): 39 Problem Description There are n people and m pairs of friends. For every pair of friends,