首页 > 代码库 > CodeForces 837F - Prefix Sums | Educational Codeforces Round 26

CodeForces 837F - Prefix Sums | Educational Codeforces Round 26

按tutorial打的我血崩,死活挂第四组- -

思路来自FXXL

/*CodeForces 837F - Prefix Sums [ 二分,组合数 ]  |  Educational Codeforces Round 26题意:	设定数组 y = f(x) 使得 y[i] = sum(x[j]) (0 <= j < i)	求初始数组 A0 经过多少次 f(x) 后 会有一个元素 大于 k分析:	考虑 A0 = {1, 0, 0, 0}		A1 = {1, 1, 1, 1}  -> {C(0,0), C(1,0), C(2,0), C(3,0)}		A2 = {1, 2, 3, 4}  -> {C(1,1), C(2,1), C(3,1), C(4,1)}		A3 = {1, 3, 6,10}  -> {C(2,2), C(3,2), C(4,2), C(5,2)}		A4 = {1, 4,10,20}  -> {C(3,3), C(4,3), C(5,3), C(6,3)}	可知任意某个元素的贡献次数可以用组合数来表示,然后二分判定	注意多个剪枝*/#include <bits/stdc++.h>using namespace std;#define LL long longconst int N = 200005;LL k, n;LL a[N];bool check(LL t){    double sum = 0, s;    LL p, q;    for (LL i = 0; i < n; i++)    {        if (a[i] == 0) continue;        q = n-1-i + t-1;        p = t-1;        p = min(p, q-p);        s = a[i];        while(p)        {            s = s*q/p;            p--, q--;            if (s >= k) return 1;        }        sum += s;        if (sum >= k) return 1;    }    return 0;}LL BinaryFind(LL l, LL r){    LL mid;    while (l <= r) {        mid = (l+r)>>1;        if (check(mid)) r = mid-1;        else l = mid+1;    }    return l;}int main(){    scanf("%lld%lld", &n, &k);    for (int i = 0; i < n; i++)    {        scanf("%lld", &a[i]);        if (a[i] >= k) {            puts("0"); return 0;        }    }    printf("%lld\n", BinaryFind(1, k));}

  

CodeForces 837F - Prefix Sums | Educational Codeforces Round 26