这道题主要是要只要一个 j += num[i] 来遍历,再加上一个lowerbound 二分一下,但是要边界设置好。
wa了N发~~
#include<bits/stdc++.h>
using namespace std;
int num[200005],vis[420010]; //这里vis要设置成200000*2,防止越界
int main() {
int n;
while(scanf("%d",&n) != EOF) {
for(int i = 0;i < n;i++)
scanf("%d",&num[i]);
sort(num,num+n);
memset(vis,0,sizeof(vis));
long long sum,ans = 0;
for(int i = 0;i < n;i++) {
sum = 0;
int l = i,pos,j;
if(!vis[num[i]]) {
vis[num[i]] = 1;
for(j = num[i]+num[i];j <= 410000;j += num[i]) { //直接设置成最大的*2,就不会有错了
vis[j] = 1;
pos = lower_bound(num,num+n,j) - num;
if(pos >= n) pos = n;
sum += (long long)(pos - l)*(long long)(j - num[i]); //这里要把值转化成long long,因为2e5*2e5会爆int!
l = pos;
}
}
ans = max(ans,sum);
}
printf("%I64d\n",ans);
}
}
继续加油了~
还有一个容斥原理写的代码更加短。回头补