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 ...
随机推荐
- 2021.12.08 [SHOI2009]会场预约(平衡树游码表)
2021.12.08 [SHOI2009]会场预约(平衡树游码表) https://www.luogu.com.cn/problem/P2161 题意: 你需要维护一个 在数轴上的线段 的集合 \(S ...
- Linux中,MySQL的常用命令
我的博客 登录 mysql -u用户名 -p -- 然后在下面输入密码,Linux的密码不会显示出,盲打就可以 mysql -u用户名 -p密码 -- 这种方式将直接登录 开关 开启数据库 servi ...
- [DEBUG] QAT Nginx for docker 部署时"--with-ld-opt"出错
layout: post title: [DEBUG] QAT Nginx for docker 部署时"--with-ld-opt"出错 subtitle: 记一次debug经历 ...
- 最佳实践 | 通过使用 Jira Service Management 改进 HR 工作流程
Jira Service Management 承诺解锁高速团队.技术团队和与之合作的业务部门都可以从 Jira Service Management中受益,尤其是 HR 团队. Atlassi ...
- viewport布局
1.viewport实例 <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <h ...
- SpringBoot从0到0.7——序言
SpringBoot从0到0.7-- 序言 最近做java代码审计发现很多地方看不懂,所以就开始学框架,自己做网站来了解网站的运行原理.函数.接口.参数等等,通过学习SpringBoot框架来从点到面 ...
- font-family样式对照表
.a { font-family: "微软雅黑" } .b { font-family: "黑体" } .c { font-family: "楷体&q ...
- FinClip小程序+Rust(三):一个加密钱包
一个加密货币钱包,主要依赖加密算法构建.这部分逻辑无关iOS还是Android,特别适合用Rust去实现.我们看看如何实现一个生成一个模拟钱包,准备供小程序开发采用 前言 在之前的内容我们介绍了整 ...
- python之名称空间与函数对象
目录 名称空间 内置名称空间 全局名称空间 局部名称空间 名称的查找顺序 作用域 global关键字 nonlocal关键字 函数名的多种用法 函数的嵌套 名称空间 名称空间就是变量名与变量值绑定关系 ...
- 一文学完Linux常用命令
一.Linux 终端命令格式 1.终端命令格式 完整版参考链接:Linux常用命令完整版 command [-options] [parameter] 说明: command : 命令名,相应功能的英 ...