CodeForces - 639C Bear and Polynomials

题目描述:

Limak is a little polar bear. He doesn't have many toys and thus he often plays with polynomials.

He considers a polynomial valid if its degree is n and its coefficients are integers not exceeding k by the absolute value. More formally:

Let a0, a1, ..., an denote the coefficients, so . Then, a polynomial P(x) is valid if all the following conditions are satisfied:

  • ai is integer for every i;
  • |ai| ≤ k for every i;
  • an ≠ 0.

Limak has recently got a valid polynomial P with coefficients a0, a1, a2, ..., an. He noticed that P(2) ≠ 0 and he wants to change it. He is going to change one coefficient to get a valid polynomial Q of degree n that Q(2) = 0. Count the number of ways to do so. You should count two ways as a distinct if coefficients of target polynoms differ.

Input

The first line contains two integers n and k (1 ≤ n ≤ 200 000, 1 ≤ k ≤ 10^{9}) — the degree of the polynomial and the limit for absolute values of coefficients.

The second line contains n + 1 integers a0, a1, ..., an (|ai| ≤ k, an ≠ 0) — describing a valid polynomial . It's guaranteed that P(2) ≠ 0.

Output

Print the number of ways to change one coefficient to get a valid polynomial Q that Q(2) = 0.

Examples

Input

3 1000000000
10 -9 -3 5

Output

3

Input

3 12
10 -9 -3 5

Output

2

Input

2 20
14 -7 19

Output

0

题目大意:

给你一个P多项式:你可以改变多项式P中的系数(题目还有约束条件,这里只是大概题意),使得P(2) = 0。问有多少种方法?

解题报告:

1:说了很多,一堆。还是删了,我决定还是举个例子,通过做这个例子,方便自己以后温习这题。

2:就拿第二组测试样例来说:

3 12
10 -9 -3 5

不修改任何系数就是这样的多项式:10+(-9)\cdot 2^{1}+(-3)\cdot 2^{2}+5\cdot 2^{3}。一步一步往2^{4}上靠近。

0+(-4)\cdot 2^{1}+(-3)\cdot 2^{2}+5\cdot 2^{3}

0+0+(-5)\cdot 2^{2}+5\cdot 2^{3}

0+0+(-1)\cdot 2^{2}+3\cdot 2^{3}

0+0+(-1)\cdot 2^{2}+1\cdot 2^{3}+1\cdot2^{4}

得到处理后的系数:0 0 -1 1 1

                     下标: 1 2  3 4 5

3:稍加思考就知道,当我们改变下标4的系数时,结果都不会影响1到3的系数,此时不管改成什么都不是使结果为0。可知只能修改到第一个不为0的系数(包括这个系数)。

4:那么答案出来了吗?答案是否定的。还有个系数的绝对值不能大于k的条件。现在我们就可以一步一步解出系数。

直接解的话肯定是会爆long long。我们可以处理到第一个不为0系数的下标idx。前面都是0相乘,可以忽略。假设原来的系数在num数组中,需要修改的系数为x,处理后的系数数组为dic,可以得到:x\cdot 2^{idx} = dic[idx+1]\cdot 2^{idx+1}+dic[idx+2]\cdot2^{idx+2}+dic[idx+3]\cdot2^{idx+3}......

两边相除,解出x。这不可以将操作倒着处理,就相当于两边都整除了2^{idx}

5:当发现对后面的后缀处理已经大于k的两倍了,就可以跳出循环了。

6:还要注意n次项的系数不能为0。

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N = 200000+10;
const ll INF = 2e9+10;
ll dic[N], idx[N];
int main(){
    ll n, k, ii;
    scanf("%lld%lld", &n, &k);
    for(ll i=0; i<=n; ++i)scanf("%lld", idx+i), dic[i] = idx[i];
    for(ll i=1; i<=n+1; ++i)dic[i] += dic[i-1]/2, dic[i-1] %= 2;
    for(ll i=0; i<=n+1; ++i){
        if(dic[i]){
            ii = i;
            break;
        }
    }
    ll x = 0, ans = 0;
    for(ll i=n+1; i>=0; --i){
        x = x*2+dic[i];
        if(abs(x) > INF)break;
        if(i > ii || i == n+1 || (i == n && x == idx[i]))continue;
        if(abs(x - idx[i]) <= k)++ans;
    }
    printf("%lld\n", ans);
    return 0;
}

可能题解写的有点乱,但仔细阅读还是可以懂的。

发布了164 篇原创文章 · 获赞 4 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/jun_____/article/details/104108167