zoukankan      html  css  js  c++  java
  • 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;
    }
    /*
    */
  • 相关阅读:
    HDOJ线段树专题(A Simple Problem with Integers)
    COJ1183(计算表达式的值)
    理解匈牙利算法求二分匹配
    COJ1143(走迷宫)
    COJ1184格林布的地雷
    POJ2387(Til the Cows Come Home)
    POJ3264(Balanced Lineup)
    调用android手机微博客户端发送微博
    用位来保存信息
    为什么类的成员变量是自身类型时只可以声明
  • 原文地址:https://www.cnblogs.com/CJLHY/p/9204203.html
Copyright © 2011-2022 走看看