Codeforces Round #489 (Div. 2)

D - Nastya and a Game

题目大意:求有多少个区间满足 区间的积/区间的和 = k

思路:我们很容易就能想到我们要在区间的积上做文章,因为如果数组里面每个数都>= 2那么 最多连乘不超过64次后面就不可能存在答案啦,

那么我们把连续的一段1缩成一个点,然后暴力枚举区间,直到区间的值大于一个数就退出循环, 里面的统计比较不好写,写挂了好几次。。

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define pii pair<int, int>

using namespace std;

const int N = 2e5 + 7;
const int M = 1e6 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 +7;

int n, k, tot;
LL a[N], b[N];
bool flag[N];
int main() {
    scanf("%d%d", &n, &k);
    for(int i = 1; i <= n; i++) {
        scanf("%lld", &a[i]);
    }

    for(int i = 1; i <= n; i++) {
        if(a[i] > 1) b[++tot] = a[i];
        else {
            int cnt = 0;
            while(i <= n && a[i] == 1) {
                i++; cnt++;
            }
            i--;
            b[++tot] = cnt;
            flag[tot] = true;
        }
    }

    LL ans = 0;
    LL up = 1e11;
    for(int i = 1; i <= tot; i++) {
        if(flag[i]) {
            if(k == 1) ans += b[i];
            continue;
        }

        LL cnt1 = 0, cnt2, now = b[i], sum = b[i];
        if(flag[i - 1]) cnt1 = b[i - 1];
        if(k == 1) ans++;
        for(int j = i + 1; j <= tot; j++) {
            if(flag[j]) {
                cnt2 = b[j];
                if(now % k == 0) {
                    LL need = now / k, all = cnt1 + cnt2;
                    if(need > sum) {
                        need -= sum;
                        all--, need--;
                        if(need <= all) {
                            ans += all - need + 1;
                            if(cnt1 > need) ans -= cnt1 - need;
                            if(cnt2 - 1 > need) ans -= cnt2 - 1 - need;
                        }
                    }
                }
                sum += b[j];
            } else {
                now *= b[j]; sum += b[j];
                if(now > up) break;

                if(now % k == 0) {
                    LL ret = now / k;
                    if(ret >= sum && ret - sum <= cnt1) {
                        ans++;
                    }
                }
            }
        }
    }
    printf("%lld
", ans);
    return 0;
}
/*
*/
原文地址:https://www.cnblogs.com/CJLHY/p/9204203.html