博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【uoj#21】[UR #1]缩进优化 数学
阅读量:4361 次
发布时间:2019-06-07

本文共 1387 字,大约阅读时间需要 4 分钟。

给出 $n$ 个数 ,求 $\text{Min}_{x=1}^{\infty}\sum\limits_{i=1}^n(\lfloor\frac {a_i}x\rfloor+a_i\ \text{mod}\ x)$ 。

$n,a_i\le 10^6$ 。


题解

数学

$\text{Min}_{x=1}^{\infty}\sum\limits_{i=1}^n(\lfloor\frac {a_i}x\rfloor+a_i\ \text{mod}\ x)=\sum\limits_{i=1}^na_i-\text{Max}_{x=1}^{a}(x-1)\sum\limits_{i=1}^{n}\lfloor\frac{a_i}x\rfloor$ 

于是枚举 $x$ ,对于某个 $x$ 我们想要知道分别有多少个 $i$ ,使得 $\lfloor\frac{a_i}x\rfloor=0,1,2,...,\lfloor\frac ai\rfloor$ 。每一个都可以使用前/后缀和求出。

总的时间复杂度 $O(n+\sum\limits_{i=1}^n\frac ai)=O(n+a\log a)$ 

#include 
#include
#include
using namespace std;long long sum[2000010];inline char nc(){ static char buf[100000] , *p1 , *p2; return p1 == p2 && (p2 = (p1 = buf) + fread(buf , 1 , 100000 , stdin) , p1 == p2) ? EOF : *p1 ++ ;}inline int read(){ int ret = 0; char ch = nc(); while(!isdigit(ch)) ch = nc(); while(isdigit(ch)) ret = ((ret + (ret << 2)) << 1) + (ch ^ '0') , ch = nc(); return ret;}int main(){ int n = read() , m = 0 , i , j , x; long long ans = 0 , mx = 0 , tmp; for(i = 1 ; i <= n ; i ++ ) x = read() , sum[x] ++ , m = max(m , x) , ans += x; for(i = m ; ~i ; i -- ) sum[i] += sum[i + 1]; for(i = 2 ; i <= m ; i ++ ) { tmp = 0; for(j = 0 ; j <= m ; j += i) tmp += j / i * (sum[j] - sum[j + i]) * (i - 1); mx = max(mx , tmp); } printf("%lld" , ans - mx); return 0;}

 

转载于:https://www.cnblogs.com/GXZlegend/p/8616920.html

你可能感兴趣的文章
缓存穿透 缓存雪崩 缓存并发
查看>>
了解你的Linux系统:必须掌握的20个命令
查看>>
js setInterval 启用&停止
查看>>
knockoutJS学习笔记04:监控属性
查看>>
Linux下启动/关闭Oracle
查看>>
session和cookie的区别
查看>>
alert弹出窗口,点击确认后关闭页面
查看>>
oracle问题之数据库恢复(三)
查看>>
单点登陆(SSO)
查看>>
HR,也确实“尽职尽责”
查看>>
MaxComputer 使用客户端配置
查看>>
20190823 顺其自然
查看>>
阅读《余生有你,人间值得》有感
查看>>
每日英语
查看>>
SpringCloud+feign 基于Springboot2.0 负载均衡
查看>>
【BZOJ5094】硬盘检测 概率
查看>>
大庆金桥帆软报表案例
查看>>
Proxy模式
查看>>
读书多些会怎样
查看>>
浏览器好用的技术
查看>>