Petrozavodsk Summer Training Camp 2015 Day 2: Xudyh (TooSimple) Contest, Saturday, August 22, 2015 E题

Problem E. Arithmetic Sequence Input file: standard input Output file: standard output Time limit: 1 seconds Memory limit: 64 mebibytes 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 how many intervals [l, r] (1 ≤ l ≤ r ≤ n) there are that al , al+1, . . . , ar are (d1, d2)-arithmetic sequence. Input First line of the input contains one integer T (1 ≤ T ≤ 15) — number of 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 ).

题目分析:

只和差分有关,存一个差分数组,找出形如 d1,d1...d1,d2,d2...d2,的统计方案数

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
const int MAXN = 1e5+100;
ll a[MAXN];
ll b[MAXN];
void Run()
{
    int n;
    ll d1,d2;
    scanf("%d%lld%lld",&n,&d1,&d2);
    for(int i=0;i<n;i++)    scanf("%lld",a+i);
    for(int i=0;i<n-1;i++)  b[i]=a[i+1]-a[i];
    int L,M,R;
    ll cnt1=0,cnt2=0;
    ll ans=n;
    n=n-2;
    //for(int i=0;i<=n;i++)   cout<<b[i]<<endl;
    int i=0;
    while(i<=n)
    {
        while(i<=n&&(b[i]!=d1&&(b[i]!=d2)))  i++;
        cnt1=0;
        while(i<=n&&b[i]==d1)   cnt1++,i++;
        cnt2=0;
        while(i<=n&&b[i]==d2)   cnt2++,i++;
        ans+=(cnt1*cnt2+(cnt1*cnt1+cnt1)/2+(cnt2*cnt2+cnt2)/2);
    }

    printf("%lld",ans);
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        Run();
        printf("
");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/poler/p/7359618.html