因为只有std,没有自我实现,所以是无码专区

主要是为了训练思维能力

solution才是dls正解,但是因为只有潦草几句,所以大部分会有我自己基于正解上面的算法实现过程,可能选择的算法跟std中dls的实现不太一样。

std可能也会带有博主自己的注释。

problem

给定 nnn 个数,选择一个子集然后加起来,统计十进制结果数位表示中有多少个 444。

对所有的 2n2^n2n 种方案,都统计一边,计算总和。

n≤40,ai≤44444444n\le 40,a_i\le 44444444n≤40,ai​≤44444444。

时限:1s256MS1s\ 256MS1s 256MS


我的想法

这种计数类题目,一般是两条线。

  • 差分然后数位 dpdpdp。
  • 每一位单独求解计算贡献,即每一位的贡献乘以这一位所在的合法情况数。

本题的 nnn 非常小,而这种 nnn 一般都是折半搜索的标志。

但是我不知道,怎么处理低位进位导致高位数字改变,这就导致了无法抽离子集本身进行求解,必须放在具体的两个子集内才能计数。


solution

折半搜索,每一位分开统计答案。

假设计算第 kkk 位为 444 的贡献。

结论:考虑两边各取一个数,分别为 s,ts,ts,t,求和为 www,如果 www 对 10k+110^{k+1}10k+1 取模后,最高位是 444,那么一定满足 s,ts,ts,t 分别对 10k+110^{k+1}10k+1 取模后再加起来的结果属于 [4×10k,5×10k)[4\times 10^k,5\times 10^k)[4×10k,5×10k) 或 [14×10k,15×10k)[14\times 10^k,15\times 10^k)[14×10k,15×10k)。

将左右两边按 10k+110^{k+1}10k+1 取模后升序排序,指针线性扫描即可。

直接排序,时间复杂度 O(2n2nlog⁡m)O(2^{\frac{n}{2}}n\log m)O(22n​nlogm),比较悬。

考虑优化,将 kkk 从小到大进行计算。

每次排序相当于是在取模 10k10^k10k 的基础上,加上了最高位。

用类似于双关键字的基排做法,在 O(2n2)O(2^{\frac{n}{2}})O(22n​) 时间内解决。

总时间复杂度 O(2n2log⁡m)O(2^\frac{n}{2}\log m)O(22n​logm)。

参考代码

#include <bits/stdc++.h>using namespace std;
const int maxn = 2e6 + 10;
struct node {long long l, r;
};
vector<node> a, b, c[10], d[10];
int n, val[maxn];void solve(int *a, int k, vector<node> &b) {for (int i = 0; i < (1 << k); i++) {long long s = 0;for (int j = 0; j < k; j++)if (i & (1 << j))s += a[j];b.push_back(node{s, 0});}
}long long get_jin0(vector<node> &a, vector<node> &b, long long base) { //处理没有进位的答案int point = b.size() - 1;long long ans = 0;for (int i = 0; i < a.size(); i++) {while (point >= 0 && a[i].r + b[point].r >= base)point--;ans += (point + 1);}return ans;
}long long get_jin1(vector<node> &a, vector<node> &b, long long base) { //处理进位后的使当前位为4的答案int point = 0;long long ans = 0;int siz = b.size();for (int i = a.size() - 1; i >= 0; i--) {while (point <= siz - 1 && a[i].r + b[point].r < base)point++;ans += (b.size() - point);}return ans;
}int main() {freopen("four.in", "r", stdin);freopen("four.out", "w", stdout);scanf("%d", &n);for (int i = 1; i <= n; i++)scanf("%d", &val[i]);solve(val + 1, n / 2, a);solve(val + 1 + n / 2, n - (n / 2), b);long long base = 1, ans = 0;for (int w = 0; w <= 8; w++) {for (int i = 0; i < 10; i++)c[i].clear(), d[i].clear();for (int i = 0; i < a.size(); i++)c[a[i].l % 10].push_back(node{a[i].l / 10, a[i].r});for (int i = 0; i < b.size(); i++)d[b[i].l % 10].push_back(node{b[i].l / 10, b[i].r});for (int i = 0; i < 10; i++) {       //枚举左半边的和的当前位的数字int k1 = (14 - i) % 10, k2 = (13 - i) %10; //求右半边对应的和的当前位的数,k1表示在不进位的情况下的值,k2表示在后面有进位的情况下的需要的ans += get_jin0(c[i], d[k1], base) + get_jin1(c[i], d[k2], base);}int now = 0;for (int i = 0; i < 10; i++)for (int j = 0; j < c[i].size(); j++)a[now++] = node{c[i][j].l, c[i][j].r + i * base};now = 0;for (int i = 0; i < 10; i++)for (int j = 0; j < d[i].size(); j++)b[now++] = node{d[i][j].l, d[i][j].r + i * base};base *= 10;}printf("%lld\n", ans);
}

【无码专区4】幸运数字4(折半搜索+计数+结论)相关推荐

  1. 【无码专区8】三角形二维数点——计数有多少个给定点落在三角形区域内

    因为只有std,没有自我实现,所以是无码专区 主要是为了训练思维能力 solution才是dls正解,但是因为只有潦草几句,所以大部分会有我自己基于正解上面的算法实现过程,可能选择的算法跟std中dl ...

  2. 【无码专区12】子集和(背包dp)

    此题已自我实现,但仍归于无码专区 本题在考场上就过了,所以难度并不高,发现性质即可. problem 有 nnn 个正整数 a1,a2,...,ana_1,a_2,...,a_na1​,a2​,... ...

  3. 【无码专区10】第K大查询(双向链表 /主席树+st表)

    已自我实现,但还是归入无码专区序列.哈哈哈哈哈 对于my idea部分,我的每一个想法都实现了,可供参考. problem 给定一个 1∼n1\sim n1∼n 的排列和 kkk,求所有 r−l+1≥ ...

  4. 【无码专区9】序列统计(带权并查集 + 前缀和建边 + dp)

    因为只有std,没有自我实现,所以是无码专区 主要是为了训练思维能力 solution才是dls正解,但是因为只有潦草几句,所以大部分会有我自己基于正解上面的算法实现过程,可能选择的算法跟std中dl ...

  5. 【无码专区2】序列划分(数学)

    有std,但是没有自我实现,所以是无码专区 description 完全由数字组成的字符串 sss,划分成若干段,每一段看成一个十进制的数(允许前导零)求有多少种划分方法使得相邻两个数至少一个是 DD ...

  6. 【无码专区3】乘法表的解密破译

    因为只有std,没有自我实现,所以是无码专区 problem 给定一个 qqq 进制的乘法表,每个字符代表着 0∼p−10\sim p-10∼p−1 不同的数字. 求每个字符代表的数字.保证有解. × ...

  7. 【无码专区13】最小公倍数(线段树)

    因为只有std,没有自我实现,所以是无码专区 主要是为了训练思维能力 my idea顾名思义,记录了我的整个思维过程,以及自己部分实现细节口胡,还有期望分数 solution才是dls正解,但是因为只 ...

  8. 【无码专区11】异或2(结论 / 推式子 + 哈希hash + 大整数高精度 加减乘除重载考察)

    本题已自我实现.但仍归于无码专区 problem 求 ∑i=1n−1i⨁(n−i)\sum_{i=1}^{n-1}i\bigoplus (n-i)∑i=1n−1​i⨁(n−i). 20%,n≤1e6; ...

  9. 【无码专区7】括号序列(思维)

    因为只有std,没有自我实现,所以是无码专区 主要是为了训练思维能力 solution才是dls正解,但是因为只有潦草几句,所以大部分会有我自己基于正解上面的算法实现过程,可能选择的算法跟std中dl ...

最新文章

  1. 分析隐藏在比特币区块链中的Pony CC服务器
  2. 【Android 事件分发】ItemTouchHelper 源码分析 ( OnItemTouchListener 事件监听器源码分析 二 )
  3. 10.21 crond定时任务练习
  4. windows的python切换环境_Windows下的python虚拟环境设置
  5. 大数据平台不是救世主!做好数字化转型,得先解决这一问题
  6. 关于创建 LINQ to SQL 类时无法转换复数的问题(zhuan)
  7. 决策树算法小结(一) ID3原理及代码实现
  8. 力扣上的代码想在本地编译运行?
  9. RN listView使用
  10. ArcGIS Pro + PS 矢量化用地规划图
  11. python 股票实时数据接口_股票行情实时数据接口
  12. 彻底解决阿里云图床上传图片,图片不显示问题
  13. python自然语言处理入门教程(一)
  14. 怎么把文件push到手机根目录_Android应用Push至设备system目录
  15. 基于cv2.VideoCapture 和 OpenCV 得到更快的 FPS之Webcam篇
  16. Linux uptime 命令(75)
  17. Linux——详解共享内存shared memory
  18. 高可用集群下的负载均衡(6):haproxy实现访问不同资源的负载均衡(日志、监控、acl访问控制的配置)
  19. 如何让Android开机不锁屏
  20. Positional Change of the Eyeball During Eye Movements: Evidence of Translatory Movement眼球运动过程中眼球的位

热门文章

  1. TensorFlow的各种应用,你晓得不?
  2. 今年不容易,要懂得爱护自己
  3. clover 主题_Clover主题更换
  4. Java千万数据导入mysql_java之5分钟插入千万条数据
  5. 法斗几个月长鼻筋_聊一下足底筋膜炎治疗经历
  6. 后端根据百度地图真实路径距离_导航软件哪家强?实测百度地图and高德地图哪个更靠谱...
  7. java string底层实现_Java-学习日记(Shell与String底层原理)
  8. 小学计算机课教学设计,小学信息技术教学设计三篇
  9. Redux从入门到进阶,看这一篇就够了!
  10. [JavaWeb-CSS]CSS概述