codeforces731F (思维)
来源:互联网 发布:unity3d ar ios 编辑:程序博客网 时间:2024/06/16 22:22
题意:给出一个数列.在数列中选取一个数,然后求把数列中的数变成小于他们的并且是这个数的倍数的数,求变化之后的数列的和最大值。
思路: 将每个数的个数记录下来,用前缀和记录下来。然后枚举每一个数,以他们的倍数进行计算出选取这个数后数列和。
以他们的倍数计算是:
比如以枚举a[i] ,那么在 a[i] * j 和 a[i] * (j + 1) - 1这个区间的数经过变换之后都是a[i] * j ,所以我们只要知道这些数的个数就能计算了,个数的话就要用到刚刚计算出的前缀和了。
PS :为了避免超时,同一个a[i]枚举过就不要枚举,所以用一个vis数组标记一下/。
#include<bits/stdc++.h>using namespace std;const int maxn = 2e6 + 10;#define INF 0x3f3f3f3ftypedef pair<int,int> P;typedef long long ll;int a[maxn];int cnt[maxn];ll sum[maxn + 100];int n;bool vis[maxn];int main(){ while( ~ scanf("%d",&n)) { memset(cnt,0,sizeof(cnt)); memset(vis,false,sizeof(vis)); int maxs = 0; for(int i = 1; i <= n;i ++) scanf("%d",&a[i]),cnt[a[i]] ++,maxs = max(maxs,a[i]); sum[0] = 0; for(int i = 1; i <= maxn; i ++) sum[i] = sum[i - 1] + cnt[i]; ll ans = 0; for(int i = 1; i <= n; i ++) { if(vis[a[i]])continue;vis[a[i]] = true; ll temp = 0; for(int j = 2; (j - 1)* a[i] <= maxs; j ++) { if(j * a[i] > maxs) { temp += (sum[maxs ] - sum[(j - 1) * a[i] - 1]) * a[i] * (j - 1); } else { temp += (sum[j * a[i] - 1] - sum[a[i]*(j - 1) - 1] )* a[i] * (j - 1); } } ans = max(ans,temp); } printf("%I64d\n",ans); } return 0;}
阅读全文
0 0
- codeforces731F (思维)
- Codeforces731F-Video Cards(暴力)
- 互联网思维-产品思维(1)
- 互联网思维-产品思维(2)
- 互联网思维-NO.1思维(1)
- 互联网思维-NO.1思维(2)
- 互联网思维-标签思维(1)
- 互联网思维-标签思维(2)
- 思维随笔(一)
- 山谷(思维)
- 创新思维(1)
- 产品思维(一)
- ZOJ 3872 (思维)
- IT思维(一)
- cf(思维题)
- cf(思维,数学)
- ZOJ 3328(思维)
- 思维题目(nyoj47)
- x的n次幂
- 猜数游戏
- E
- CodeForces B. Karen and Coffee
- 操作EEPROM时触发ECC内部故障导致通信失败
- codeforces731F (思维)
- 循环结构
- (转)为了快 0.00007 秒,有家交易公司花 1400 万美元买了块地
- 用Java代码实现改变一个文本中的内容,即将一个文本里的内容修改内容,并存储到另一个文本中
- 编程练习——顺时针打印矩阵
- 【CSS 基础】01 概述
- [注释转化]C语言注释转换为C++语言注释
- epoll和select
- hdu 1564 Play a game