构造 HDOJ 5400 Arithmetic Sequence

题目传送门

题意:问有多少个区间,其中存在j使得ai + d1 == ai+1(i<j) && ai + d2 == ai+1 (i>j)

构造:用c1[i], c2[i]记录i为标杆左边最多几个符合以及右边最多几个符合,那么i的贡献为(c1[i]+1) * (c2[i] + 1);当d1==d2时,找出符合的连续区间,长度记为cnt,那么贡献为(cnt+1) * cnt / 2。

/************************************************
* Author        :Running_Time
* Created Time  :2015-8-18 12:27:51
* File Name     :E.cpp
************************************************/

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <cstdlib>
#include <ctime>
using namespace std;

#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
typedef long long ll;
const int MAXN = 1e5 + 10;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
int a[MAXN];
ll c1[MAXN], c2[MAXN];

int main(void)    {     //HDOJ 5400 Arithmetic Sequence
   int n, d1, d2;
   while (scanf ("%d%d%d", &n, &d1, &d2) == 3) {
       for (int i=1; i<=n; ++i)    {
           scanf ("%d", &a[i]);
       }
       memset (c1, 0, sizeof (c1));
       memset (c2, 0, sizeof (c2));
       for (int i=2; i<=n; ++i)    {
           if (a[i-1] + d1 == a[i])    c1[i] = c1[i-1] + 1;
       }
       for (int i=n; i>=2; --i)    {
           if (a[i-1] + d2 == a[i])    c2[i-1] = c2[i] + 1;
       }

       ll ans = 0;
       if (d1 == d2)   {
           ll cnt = 1;
           for (int i=2; i<=n; ++i)    {
               if (a[i] - a[i-1] == d1)    cnt++;
               else    {
                   ans += (cnt + 1) * cnt / 2; cnt = 1;
               }
           }
           ans += (cnt + 1) * cnt / 2;
           printf ("%I64d ", ans);    continue;
       }
       for (int i=1; i<=n; ++i)    {
           ans += (c1[i] + 1) * (c2[i] + 1);
       }
       printf ("%I64d ", ans);
   }

   return 0;
}
编译人生,运行世界!
原文地址:https://www.cnblogs.com/Running-Time/p/4741942.html