bzoj1607: [Usaco2008 Dec]Patting Heads 轻拍牛头

筛法。

枚举每个数,它会对它的倍数的答案有贡献。

数大了以后,倍数相应少了很多。比枚举每个数的约数要好的多。

自己yy了一种分步做法。小于sqrt(m)被当作约数枚举,大于sqrt(m)的枚举倍数。

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 1000000 + 10;

int a[maxn],cnt[maxn];
int n,maxa,s[maxn];

int main() {
    scanf("%d",&n);
    for(int i=1;i<=n;i++) {
        scanf("%d",&a[i]);
        cnt[a[i]]++;
        maxa=max(maxa,a[i]);
    }
    for(int i=1;i<=maxa;i++) {
        if(cnt[i]) 
        for(int j=i;j<=maxa;j+=i) s[j]+=cnt[i];
    }
    for(int i=1;i<=n;i++) printf("%d\n",s[a[i]]-1);
    return 0;
}
posted @ 2016-05-20 19:36  invoid  阅读(145)  评论(0编辑  收藏  举报