牛客网暑期ACM多校训练营(第三场): C. Chiaki Sequence Reloaded(数位DP)
题目描述
Chiaki is interested in an infinite sequence a1, a2, a3, ..., which defined as follows:
Chiaki would like to know the sum of the first n terms of the sequence, i.e. . As this number may be very large, Chiaki is only interested in its remainder modulo (109 + 7).
输入描述:
There are multiple test cases. The first line of input contains an integer T (1 ≤ T ≤ 105), indicating the number of test cases. For each test case: The first line contains an integer n (1 ≤ n ≤ 1018).
输出描述:
For each test case, output an integer denoting the answer.
题意:求上面的公式的绝对值的前缀和
打表可以看出a[i] = (i的2进制表示下:相邻位相同的个数 - 相邻位不同的个数),例如a[13(1101)] = 1-2 = -1
然后就可以求数位DP了,因为i的2进制最高只有64位,所以a[i]的取值范围大概是[-64, 64],可以考虑暴力每个值各出现多少次
预处理sum[x][y][z]表示当前暴力到第x位,且第x位为y,有多少个数满足a[]值为z(包含前导0)
例如sum[5][1][-3]就表示刚好有5位,且最高位为1,且满足a[k]为-3的二进制k的个数,有转移
for(i=2;i<=66;i++)
{for(j=1;j<=135;j++) //因为数组下标不能为负数,所以需要整体移位:[-64,64]→[1,129]{sum[i][0][j] = (sum[i-1][0][j-1]+sum[i-1][1][j+1])%mod;sum[i][1][j] = (sum[i-1][1][j-1]+sum[i-1][0][j+1])%mod;}
}
之后对于每一个询问n,从n的最高位开始,如果当前位为1,那么很显然将这一位改成0之后后面所有的数字都可以01任取,与此同时你可以算出前面的(二进制相邻位相同的个数 - 相邻位不同的个数),这样只需要算上你预处理的sum[]就可以求出当前位对答案的贡献了,不过直接暴力sum[]还是会超时,所以还需要对sum再求一次前缀和
超时但好理解的程序:
#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
#define LL long long
LL sum[88][2][222], a[88];
int main(void)
{LL T, n, i, j, len, ans, now, p;sum[1][0][100] = sum[1][1][100] = 1;for(i=2;i<=66;i++){for(j=1;j<=200;j++){sum[i][0][j] = sum[i-1][0][j-1]+sum[i-1][1][j+1];sum[i][1][j] = sum[i-1][1][j-1]+sum[i-1][0][j+1];}}scanf("%lld", &T);while(T--){len = 0;scanf("%lld", &n);while(n){a[++len] = n%2;n /= 2;}ans = now = 0;for(i=len;i>=1;i--){p = 0;if(i!=len && a[i]!=a[i+1]) p = -1;else if(i!=len) p = 1;if(a[i]){if(i!=len){for(j=1;j<=200;j++)ans += sum[i][0][j]*abs(j-100+now-p);}}if(i!=len){for(j=1;j<=200;j++)ans += sum[i][1][j]*abs(j-100);}now += p;}ans += abs(now);printf("%lld\n", ans);}return 0;
}
AC代码(附打表程序):
#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
#define LL long long
#define mod 1000000007
LL sum[70][2][138], Q[70][2][138], a[88];
int main(void)
{LL T, n, i, j, k, len, ans, now, p;sum[1][0][65] = sum[1][1][65] = 1;for(i=2;i<=66;i++){for(j=1;j<=135;j++) //因为数组下标不能为负数,所以需要整体移位:[-64,64]→[1,129]{sum[i][0][j] = (sum[i-1][0][j-1]+sum[i-1][1][j+1])%mod;sum[i][1][j] = (sum[i-1][1][j-1]+sum[i-1][0][j+1])%mod;}}for(i=1;i<=66;i++){for(k=1;k<=135;k++){for(j=1;j<=135;j++){Q[i][0][k] = (Q[i][0][k]+sum[i][0][j]*abs(j-k))%mod;Q[i][1][k] = (Q[i][1][k]+sum[i][1][j]*abs(j-k))%mod;}}}scanf("%lld", &T);while(T--){len = 0;scanf("%lld", &n);while(n){a[++len] = n%2;n /= 2;}ans = now = 0;for(i=len;i>=1;i--){p = 0;if(i!=len && a[i]!=a[i+1]) p = -1;else if(i!=len) p = 1;if(a[i]){if(i!=len)ans = (ans+Q[i][0][65-now+p])%mod;//sum[i][0][j]*abs(j-65+now-p);}if(i!=len)ans = (ans+Q[i][1][65])%mod;now += p;}ans = (ans+abs(now))%mod;printf("%lld\n", ans);}return 0;
}
/*#include<stdio.h>
#include<stdlib.h>
int F[10005], S[10005];
void Jud(int x)
{if(x<=1)printf("%d", x);else{Jud(x/2);printf("%d", x%2);}
}
int main(void)
{int i;for(i=1;i<=9999;i++){if(i==1)F[i] = 0;else{if(i%4==2 || i%4==1)F[i] = F[i/2]-1;elseF[i] = F[i/2]+1;}//printf("%-5d", i);//Jud(i);//printf(": %d\n", F[i]);S[i] = abs(F[i])+S[i-1];if(i<=15 || i==7788)printf("%d\n", S[i]);}return 0;
}*/
牛客网暑期ACM多校训练营(第三场): C. Chiaki Sequence Reloaded(数位DP)相关推荐
- 牛客网暑期ACM多校训练营(第三场): E. Sort String(KMP)
链接:https://www.nowcoder.com/acm/contest/141/E 来源:牛客网 题目描述 Eddy likes to play with string which is a ...
- 牛客网暑期ACM多校训练营(第三场): C. Shuffle Cards(splay)
链接:https://www.nowcoder.com/acm/contest/141/C 来源:牛客网 题目描述 Eddy likes to play cards game since there ...
- 牛客网暑期ACM多校训练营(第三场): A. Ternary String(欧拉降幂+递推)
题目描述 A ternary string is a sequence of digits, where each digit is either 0, 1, or 2. Chiaki has a t ...
- 牛客网暑期ACM多校训练营(第九场)
牛客网暑期ACM多校训练营(第九场) A. Circulant Matrix 做法:看到下标 \(xor\) 这种情况就想 \(FWT\),可是半天没思路,于是放弃了..其实这个 \(n\) 疯狂暗示 ...
- 牛客网暑期ACM多校训练营(第一场)
牛客网暑期ACM多校训练营(第一场) A. Monotonic Matrix 考虑0和1的分界线,1和2的分界线,发现问题可以转化为两条不互相穿过的路径的方案数(可重叠),题解的做法就是把一条路径斜着 ...
- 牛客网暑期ACM多校训练营(第二场): H. travel(树形线头DP)
链接:https://ac.nowcoder.com/acm/contest/140/H 来源:牛客网 题目描述 White Cloud has a tree with n nodes.The roo ...
- 牛客网暑期ACM多校训练营(第二场)A .run
链接:https://www.nowcoder.com/acm/contest/140/A 来源:牛客网 题目描述 White Cloud is exercising in the playgroun ...
- 牛客网暑期ACM多校训练营(第一场) J (莫队算法)
题目链接:https://www.nowcoder.com/acm/contest/139/J 题目大意:给一个序列,进行q次查询,问1~l和r~n中有多少个不同的数字 题目思路:之前只是听说过莫队算 ...
- 牛客网暑期ACM多校训练营(第二场)J farm (二维树状数组)
题目链接: https://www.nowcoder.com/acm/contest/140/J 思路: 都写在代码注释里了,非常好懂.. for_each函数可以去看一下,遍历起vector数组比较 ...
最新文章
- vue实用组件——页面公共头部
- 碰疼了会躲!这个植入“迷你大脑”的AI机器人,可感知疼痛,还能自我愈合...
- css属性 background
- JavaEE 银联支付之网站支付-消费类交易
- 假如地球变成甜甜圈形状,世界会变成什么样子?
- SAP License:ERP面试记
- PY++ 自动将你的C++程序接口封装供python调用
- 通过创建制定版本react-native项目解决“Unable to resolve module `AccessibilityInfo` ”的问题...
- matlab中.mat文件用法
- 关于融资融券和转融通
- Java标准教程:Java 2D绘图--第4章 使用Text API
- 深度学习基础----GAE和VGAE
- iOS 画板 涂鸦 答题
- win7 win8.1搜索不到隐藏中文wifi 已添加隐藏wifi但是没显示
- python第一行代码_“少年py”001:下载Python软件,写第一行代码
- matlab牛顿法解非线性方程组,matlab实现牛顿迭代法求解非线性方程组.pdf
- Linux 音频驱动(四) ASoC音频驱动之Machine驱动
- npm发布项目报404错误解决
- Python大数据分析与应用—2020年中国高校毕业生薪酬指数排名
- c++ opencv 图像处理:直方图处理(直方图均衡化,直方图匹配(规定化))
热门文章
- 如何系统的自学python-如何系统的学习python?
- python从入门到精通pdf下载-Python网络爬虫从入门到精通 PDF 下载
- 消费者生产者代码之---一步一步带你写
- React-setState修改状态
- 小程序 报request:fail invalid url 不校验合法域名已勾选
- mac m1 nvm 安装node版本失败
- dfs记忆化搜索(带限制的选择问题) 讲解:LeetCode打家劫舍||| / 蓝桥 地宫取宝/蓝桥 k进制数//剪格子//方格分割
- 【数据结构和算法笔记】KMP算法介绍
- php 上传没生成文件,php-上传时无法创建临时文件
- ggbiplot设置分组_prcomp和ggbiplot:无效的’rot’值