题目描述

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)相关推荐

  1. 牛客网暑期ACM多校训练营(第三场): E. Sort String(KMP)

    链接:https://www.nowcoder.com/acm/contest/141/E 来源:牛客网 题目描述 Eddy likes to play with string which is a ...

  2. 牛客网暑期ACM多校训练营(第三场): C. Shuffle Cards(splay)

    链接:https://www.nowcoder.com/acm/contest/141/C 来源:牛客网 题目描述 Eddy likes to play cards game since there ...

  3. 牛客网暑期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 ...

  4. 牛客网暑期ACM多校训练营(第九场)

    牛客网暑期ACM多校训练营(第九场) A. Circulant Matrix 做法:看到下标 \(xor\) 这种情况就想 \(FWT\),可是半天没思路,于是放弃了..其实这个 \(n\) 疯狂暗示 ...

  5. 牛客网暑期ACM多校训练营(第一场)

    牛客网暑期ACM多校训练营(第一场) A. Monotonic Matrix 考虑0和1的分界线,1和2的分界线,发现问题可以转化为两条不互相穿过的路径的方案数(可重叠),题解的做法就是把一条路径斜着 ...

  6. 牛客网暑期ACM多校训练营(第二场): H. travel(树形线头DP)

    链接:https://ac.nowcoder.com/acm/contest/140/H 来源:牛客网 题目描述 White Cloud has a tree with n nodes.The roo ...

  7. 牛客网暑期ACM多校训练营(第二场)A .run

    链接:https://www.nowcoder.com/acm/contest/140/A 来源:牛客网 题目描述 White Cloud is exercising in the playgroun ...

  8. 牛客网暑期ACM多校训练营(第一场) J (莫队算法)

    题目链接:https://www.nowcoder.com/acm/contest/139/J 题目大意:给一个序列,进行q次查询,问1~l和r~n中有多少个不同的数字 题目思路:之前只是听说过莫队算 ...

  9. 牛客网暑期ACM多校训练营(第二场)J farm (二维树状数组)

    题目链接: https://www.nowcoder.com/acm/contest/140/J 思路: 都写在代码注释里了,非常好懂.. for_each函数可以去看一下,遍历起vector数组比较 ...

最新文章

  1. vue实用组件——页面公共头部
  2. 碰疼了会躲!这个植入“迷你大脑”的AI机器人,可感知疼痛,还能自我愈合...
  3. css属性 background
  4. JavaEE 银联支付之网站支付-消费类交易
  5. 假如地球变成甜甜圈形状,世界会变成什么样子?
  6. SAP License:ERP面试记
  7. PY++ 自动将你的C++程序接口封装供python调用
  8. 通过创建制定版本react-native项目解决“Unable to resolve module `AccessibilityInfo` ”的问题...
  9. matlab中.mat文件用法
  10. 关于融资融券和转融通
  11. Java标准教程:Java 2D绘图--第4章 使用Text API
  12. 深度学习基础----GAE和VGAE
  13. iOS 画板 涂鸦 答题
  14. win7 win8.1搜索不到隐藏中文wifi 已添加隐藏wifi但是没显示
  15. python第一行代码_“少年py”001:下载Python软件,写第一行代码
  16. matlab牛顿法解非线性方程组,matlab实现牛顿迭代法求解非线性方程组.pdf
  17. Linux 音频驱动(四) ASoC音频驱动之Machine驱动
  18. npm发布项目报404错误解决
  19. Python大数据分析与应用—2020年中国高校毕业生薪酬指数排名
  20. c++ opencv 图像处理:直方图处理(直方图均衡化,直方图匹配(规定化))

热门文章

  1. 如何系统的自学python-如何系统的学习python?
  2. python从入门到精通pdf下载-Python网络爬虫从入门到精通 PDF 下载
  3. 消费者生产者代码之---一步一步带你写
  4. React-setState修改状态
  5. 小程序 报request:fail invalid url 不校验合法域名已勾选
  6. mac m1 nvm 安装node版本失败
  7. dfs记忆化搜索(带限制的选择问题) 讲解:LeetCode打家劫舍||| / 蓝桥 地宫取宝/蓝桥 k进制数//剪格子//方格分割
  8. 【数据结构和算法笔记】KMP算法介绍
  9. php 上传没生成文件,php-上传时无法创建临时文件
  10. ggbiplot设置分组_prcomp和ggbiplot:无效的’rot’值