Codeforces 992D. Nastya and a Game

题意:给定一个数组,求子数组的乘积/子数组的和=k的个数

分析:由于ai的范围是1e8,n是2e5。和最多为1e13,k最大是1e5,所以子数组乘积最多不超过2e18,乘以1时候乘积不变,跳过所有的1,每次按照乘以2的话最多乘60次,复杂度为O(n * 60)。有

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 10;
ll a[maxn];
int cnt[maxn];
const ll INF = 2e18;
int main()
{
    ll n,k;
    cin>>n>>k;
    for(int i = 1; i <= n; i++)
        cin>>a[i];
    int res = 0;
    for(int i = n; i >= 1; i--)
    {
        if(a[i] == 1)
        {
            cnt[i - 1] = cnt[i] + 1;
        }
    }
    for(int i = 1; i <= n; i++)
    {
        ll sum = 0,mul = 1LL;
        for(int j = i; j <= n; j++)//跳过所有的1,最多不超过60次
        {
           sum += a[j];
           if(mul > INF / a[j])//注意直接乘会爆long long 
              break;
           mul *= a[j];
          if(sum * k == mul)
            res++;
          else
          {
              if(sum * k < mul && (mul % k == 0) && (mul / k >= sum) && (mul / k <= sum + cnt[j]))
                  res++;
              int x = cnt[j];
              j += x;
              sum += x;//j变了
          }
        }
    }
    cout<<res<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/zhlbjtu2016/article/details/81264573