湖南大学ACM程序设计新生杯大赛(同步赛)A - Array

题目描述

Given an array A with length n  a[1],a[2],...,a[n] where a[i] (1<=i<=n) is positive integer.
Count the number of pair (l,r) such that a[l],a[l+1],...,a[r] can be rearranged to form a geometric sequence.
Geometric sequence is an array where each term after the first is found by multiplying the previous one by a fixed, non-zero number called the common ratio. i.e. A = [1,2,4,8,16] is a geometric sequence.

输入描述:

The first line is an integer n (1 <= n <= 100000).
The second line consists of n integer a[1],a[2],...,a[n] where a[i] <= 100000 for 1<=i<=n.

输出描述:

An integer answer for the problem.
示例1

输入

5
1 1 2 4 1

输出

11

说明

The 11 pairs of (l,r) are (1,1),(1,2),(2,2),(2,3),(2,4),(3,3),(3,4),(3,5),(4,4),(4,5),(5,5).
示例2

输入

10
3 1 1 1 5 2 2 5 3 3

输出

20

备注:

The answer can be quite large that you may use long long in C++ or the similar in other languages.

题解

暴力。

先统计公比为$1$的区间有几种,接下来,无论公比为多少,区间长度不会超过$17$,因此只要枚举区间起点,验证$17$个区间即可。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
 
const int maxn = 100000 + 10;
int n;
long long a[maxn];
long long b[maxn];
int sz;
 
int check() {
  if(b[0] == b[sz - 1]) return 0;
  if(sz == 2) return 1;
  for(int i = 2; i < sz; i ++) {
    if(b[1] * b[i - 1] != b[0] * b[i]) return 0;
  }
  return 1;
}
 
int main() {
  while(~scanf("%d", &n)) {
    for(int i = 1; i <= n; i ++) {
      scanf("%lld", &a[i]);
    }
    long long ans = 1;
    long long sum = 1;
    for(int i = 2; i <= n; i ++) {
      if(a[i] == a[i - 1]) sum ++;
      else sum = 1;
      ans = ans + sum;
    }
    for(int i = 1; i <= n; i ++) {
      sz = 0;
      for(int j = i; j <= min(n, i + 20); j ++) {
        b[sz ++] = a[j];
        int p = sz - 1;
        while(p && b[p] < b[p - 1]) {
          swap(b[p], b[p - 1]);
          p --;
        }
        ans = ans + check();
      }
    }
    printf("%lld\n", ans);
  }
  return 0;
}

  

posted @ 2017-12-24 20:11  Fighting_Heart  阅读(351)  评论(0编辑  收藏  举报