NC14380 位数差
NC14380 位数差
题目
题目描述
给一个数组 \({a}\) ,定义 \(h(a,b)\) 为在十进制下 \(a + b\) 与 \(a\) 的位数差,求 \(\displaystyle\sum_{1\leq i < j \leq n} h(a_i,a_j)\),\(0\) 的位数为 \(1\) 。
输入描述
第一行读入一个正整数 \(n (1 <= n <= 10^5)\)。第二行读入 \(n\) 个非负整数,第 \(i\) 个表示 \(a[i] (0 <= a[i] <= 10^8)\) 。
输出描述
一行表示答案。
示例1
输入
10
0 1 2 3 4 5 6 7 8 9
输出
20
题解
思路
知识点:二分,数学。
我们用 \(bit(a)\) 表示 \(a\) 的十进制位数,则有:
\displaystyle\sum_{1\leq i < j \leq n} h(a_i,a_j) &= \displaystyle\sum_{1\leq i < j \leq n} bit(a_i+a_j) - bit(a_i)\\
&=\displaystyle\sum_{1\leq i < j \leq n} bit(a_i+a_j) - \displaystyle\sum_{1\leq i < j \leq n}bit(a_i)\\
&=\displaystyle\sum_{1\leq i < j \leq n} bit(a_i+a_j) - \displaystyle\sum_{1\leq i \leq n}(n-i)bit(a_i)\\
&=\displaystyle\sum_{1\leq i < j \leq n} bit(a_i+a_j) - \displaystyle\sum_{1\leq i < j \leq n}(n-i)bit(a_i)\\
\end{align*}
\]
其中,\(- \displaystyle\sum_{1\leq i < j \leq n}(n-i)bit(a_i)\) 可以在输入时候处理完。
而 \(\displaystyle\sum_{1\leq i < j \leq n} bit(a_i+a_j)\) 与 \(i\) 和 \(j\) 顺序可以互换,因此该式与序列的排列顺序无关。所以从小到大排序,对每一个数查找某一结果的区间,由于选择比 \(a_i\) 小的数与 \(a_i\) 配对答案只可能是 \(0\) 和 \(1\) 而选择大的数会出现 \(0\) 到 \(9\) ,而选择一种即可结果是相同的,我们选择前者查找答案 \(01\) 分界点,非常方便。显然只要查找大于等于 \(10^{bit(a_i)} - a_i\) 的第一个数 \(a_{pos}\),即第一个 \(bit(a_i+a_j)\) 结果为 \(bit(a_i)+1\) 的数即可。随后因为这个区间的所有数的位数至少是 \(bit(a_i)\) ,因此加上 \((i-1)bit(a_i)\) ,再加上位数多一的个数 \((i-pos)\) ,于是对于这个数与小于他的数的配对总和就是 \((i-1)bit(a_i)+(i-pos)\) ,对每个数如此操作即可。
时间复杂度 \(O(n \log n)\)
空间复杂度 \(O(n)\)
代码
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int a[100007];
int p[10] = { 1,10,100,1000,10000,100000,1000000,10000000,100000000 };
int bit(int n) {
if (!n) return 1;
int ans = 0;
while (n) n /= 10, ans++;
return ans;
}
int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int n;
cin >> n;
ll ans = 0;
for (int i = 1;i <= n;i++) cin >> a[i], ans -= (n - i) * bit(a[i]);
sort(a + 1, a + n + 1);
for (int i = 1;i <= n;i++) {
int pos = lower_bound(a + 1, a + i, p[bit(a[i])] - a[i]) - a;
ans += (i - 1) * bit(a[i]) + (i - pos);
}
cout << ans << '\n';
return 0;
}
NC14380 位数差的更多相关文章
- 常州Day4题解
1. 高精度 这题略水,字符串可过,还不加压位等,操作只有BitShift和add/sub,不过编程复杂度有些高.(输出都是二进制我能说些什么...) 2. N皇后问题 (警告! 不是平时你见到的N皇 ...
- 大数运算的算法设计和C++实现
1.背景 工作中遇到过需要进行极大数据的存储和运算的场景,当时使用Python解决了这个问题,在Python中,整数没有位数限制,使用起来很方便.但是当程序主体使用C/C++实现时,就比较麻烦.所以考 ...
- POJ 1035 Spell checker (模拟)
题目链接 Description You, as a member of a development team for a new spell checking program, are to wri ...
- 网络基础之IP地址和子网掩码
IP地址 IP是英文Internet Protocol的缩写,意思是"网络之间互连的协议",也就是为计算机网络相互连接进行通信而设计的协议.在因特网中,它是能使连接到网上的所有计算 ...
- Codeforces 608B. Hamming Distance Sum 模拟
B. Hamming Distance Sum time limit per test: 2 seconds memory limit per test:256 megabytes input: st ...
- iOS关于版本更新的问题
// 获取app版本 NSString *app_Version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBun ...
- 无限小数转分数POJ1930分析
将无限小数化为分数,有一套简单的公式.使其轻松表示出来. 循环节 例如:0.121212…… 循循环节为12. 公式 这个公式必须将循环节的开头放在十分位.若不是可将原数乘10^x(x为正整数) ...
- js处理浮点数计算误差
众所周知,浮点计算会产生舍入误差的问题,比如,0.1+0.2,结果应该是0.3,但是计算的结果并不是如此,而是0.30000000000000004,这是使用基于IEEE754数值的浮点计算的通病,j ...
- POJ 2718 Smallest Difference(贪心 or next_permutation暴力枚举)
Smallest Difference Description Given a number of distinct decimal digits, you can form one integer ...
随机推荐
- DFA算法之内容敏感词过滤
DFA 算法是通过提前构造出一个 树状查找结构,之后根据输入在该树状结构中就可以进行非常高效的查找. 设我们有一个敏感词库,词酷中的词汇为:我爱你我爱他我爱她我爱你呀我爱他呀我爱她呀我爱她啊 那么就可 ...
- IDEA打包javaFX及踩坑解决
开门见山的说,先打包,再说坑. File-->Project Structure --> Artifacts-->(此处点加号)JAR-->From modules with ...
- Es5 - 11 详解
一.ES简介 ECMAScript,欧洲计算机制造商协会 ES是一种标准,而JS是ES的一种实现 每年的ES版本中都会引入新特性 二.NRM的安装与使用 NRM是切换源的工具 ES6 2.1安装 wi ...
- SpringBoot详解
1.Hello,World! 1.1.SpringBoot简介 回顾什么是Spring Spring是一个开源框架,2003 年兴起的一个轻量级的Java 开发框架,作者:Rod Johnson . ...
- 排序算法详解(java代码实现)
排序算法大致分为内部排序和外部排序两种 内部排序:待排序的记录全部放到内存中进行排序,时间复杂度也就等于比较的次数 外部排序:数据量很大,内存无法容纳,需要对外存进行访问再排序,把若干段数据一次读 ...
- Linux 运维请务必收藏~ Nginx 五大常见应用场景
关注「开源Linux」,选择"设为星标" 回复「学习」,有我为您特别筛选的学习资料~ Nginx 是一个很强大的高性能 Web 和反向代理服务,它具有很多非常优越的特性,在连接高并 ...
- 一文详解 Ansible 自动化运维
开源Linux 一个执着于技术的公众号 一.Ansible 概述 Ansible 是近年来越来越火的一款开源运维自动化工具,通过Ansible可以实现运维自动化,提高运维工程师的工作效率,减少人为失误 ...
- 测试覆盖率 之 Cobertura的使用
什么是代码覆盖率? 代码覆盖率是对整个测试过程中被执行的代码的衡量,它能测量源代码中的哪些语句在测试中被执行,哪些语句尚未被执行. 为什么要测量代码覆盖率? 众所周知,测试可以提高软件版本的质量和可预 ...
- muduo源码分析之回调模块
这次我们主要来说说muduo库中大量使用的回调机制.muduo主要使用的是利用Callback的方式来实现回调,首先我们在自己的EchoServer构造函数中有这样几行代码 EchoServer(Ev ...
- C++进阶-3-5-list容器
C++进阶-3-5-list容器 1 #include<iostream> 2 #include<list> 3 #include<algorithm> 4 usi ...