Codeforces 658D Bear and Polynomials【数学】
2016-03-29 17:12
411 查看
题目链接:
http://codeforces.com/contest/658/problem/D题意:
给定合法多项式,改变一项的系数,使得P(2)=0,问有多少种方法?分析:
暴力求和然后依次试一试肯定不行啦~仔细想想,多项式和为0,就是说存在某个2i,使得剩下的和等于x∗2i,(其中x 的绝对值小于等于k)。
那我们就从最小的开始看。把系数依次向后移。
如果系数ai为偶数,那么ai∗2i=(ai/2)∗2i+1,就令bi=0,否则bi=1,最终所有系数都移到了2n上。
如果某个bi为奇数的话,就是说不能完全转化成后面的数,无法用比他大的数表示他,那么后面的系数怎么变也抵消不了。所以我们只能看他自己和他前面的元素,通过改变这些元素的系数试图抵消它。
最后倒着算一遍,算出对于每个位置,可以抵消后面的数的系数,然后。。。减一下他自己。。。就可以了。。。。
然后注意一下倒着求和过程中res的绝对值大于INF的情况,直接break。
代码:
#include <cstdio> const int maxn = 200005, INF = 1e18; long long t[maxn],a[maxn], b[maxn]; int main (void) { int n, k; long long res = 0; scanf("%d%d",&n, &k); for(int i = 0; i <= n; i++){ scanf("%I64d",&a[i]); } b = a ; int flag; for(int i = 0; i < n; i++){ int tmp = b[i] + a[i] ; b[i + 1] += tmp / 2ll; b[i] = tmp % 2ll; } for(int i = 0; i <= n; i++){ if(b[i]){flag = i; break;}//记录 } int cnt = 0; for(int i = n; i >= 0; i--){ res = res * 2ll + b[i]; if(res > INF || res < -INF )break; if(i <= flag){ int ans = a[i] - res; if(ans >= -k && ans <= k && (ans != 0 || i != n)){ cnt++; } } } printf("%d\n", cnt); } /* 5 5 0 -4 -2 -2 0 5 */
智商压制,想的有点久。。。不过还是涨姿势!
相关文章推荐
- 项目开发主键生成知多少
- RTX中自定义群组 BAT批处理模式修改自定义内容
- nagios安装过程中遇到的问题
- JavaScript跨域访问
- openwrt Web刷写新的固件提示文件格式问题
- Linux 内存管理分析
- 72.ARC中的 strong指针和weak指针
- Mysql 复制-基于GTID 测试
- unity3d 更换sprite renderer中sprite的图片
- Linux的常用命令<1>
- IOS学习之——xib的创建 自定义View
- javascript跳跃式前进(1) - 基本概念
- 屏蔽浏览器默认事件 之 只能输入数字框的文本框
- 第三次作业
- attributesOfItemAtPath:方法的使用
- 我对java IO流简单的理解
- HDU 2082 找单词
- Fragment的初步使用
- 排序-冒泡排序最终优化版本
- 跨平台的视频采集、直播SDK SmarterStreaming