2014/11/25
等会还要抄马克思的作业和期中考卷子,不能刷题了。
NlogN的经典模型应用面并不单一,据我所知 素数打表的优化中有它, 背包二进制优化中有它。
具体它的神奇之处在哪里,我直接放题目和代码,不多说滚去抄卷子了。
题面是我自己编的,模型题有空再放。
Σ Max(a[ i ] % a[ j ] )
现在Waking想让这个题目变得有趣点。现在在一个序列n中有
a[i]%a[j] 的存在,当然a[j]确定时 存在 a[i]%a[j] 最大的值 max。对于每个a[j]来说都有一个maxj,求 Σmaxj。(注意:1<= i,j<= n,a[i] >= a[j])
2<= n <= 200005 , 0<=a[i]<=1000000.
输入:
输入一个n;
接下来一行输入n个数。
输出:
每行输出一个答案。
样例输入:
3
3 4 5
5
5 8 8 9 10
样例输出:
3
9
提示:
第二组样例:9%5 = 4,10%8 = 2,9 %10 = 1, 10%10 = 0。4+2*2+1= 9.
#include<stdio.h>
#include<string.h>
#include<algoritHm>
using namespace std;
int s[2000005];
int s1[1000005];
int Max(int a,int b)
{
return a>b?a:b;
}
int main()
{
//freopen("data.in", "r", stdin);
//freopen("data.out", "w", stdout);
int n, x;
while(~scanf("%d",&n))
{
int sum = 0;
memset(s,0,sizeof(s));
memset(s1,0,sizeof(s1));
for(int i= 0;i < n; i++)
{
scanf("%d",&x);
s[x] = x;
s1[x]++;
}
for(int i = 1;i <= 2000000; i++)
{
if(s[i]!=i)s[i] =s[i-1];
}
for(int i = 2;i <= 1000000; i++)
{
if(s[i] == i)
{
int ans = i+i;
int maxn = 0;
while(ans <= 2000000)
{
maxn = Max(maxn,s[ans-1]%i);
ans+=i;
}
sum+=maxn*s1[i];
}
}
printf("%d\n",sum);
}
return 0;
}