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; }