【BZOJ1607】[Usaco2008 Dec]Patting Heads 轻拍牛头

描述 Description

今天是贝茜的生日,为了庆祝自己的生日,贝茜邀你来玩一个游戏.

贝茜让 N(1≤N≤100000) 头奶牛坐成一个圈.除了 1 号与 N 号奶牛外,i 号奶牛与 i-l 号和 i+l 号奶牛相邻.N 号奶牛与 1 号奶牛相邻.农夫约翰用很多纸条装满了一个桶,每一张包含了一个独一无二的 1 到 1,000,000 的数字.

接着每一头奶牛 i 从柄中取出一张纸条 Ai.每头奶牛轮流走上一圈,同时拍打所有编号能整除在纸条上的数字的牛的头,然后做回到原来的位置.牛们希望你帮助他们确定,每一头奶牛需要拍打的牛.

输入格式 InputFormat

第 1 行包含一个整数 N,接下来第 2 到 N+1 行每行包含一个整数 Ai.

输出格式 OutputFormat

第 1 到 N 行,每行的输出表示第 i 头奶牛要拍打的牛数量.

样例输入 SampleInput

12
3
19
12
6
4
16
16
15
1
4
7
12

样例输出 SampleOutput

1
1
6
2
2
4
4
2
0
2
1
6

来源 Source

Silver


BZOJ 1607


代码 Code

求约数个数的题目,用类似筛法的方法做。

#include <stdio.h>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
int a[100005],b[100005];
int c[1000005],f[2000005];
int i,j,t,n,m,l,r,k,z,y,x,xmax;
int main()
{
    memset(c,0,sizeof(c));
    memset(f,0,sizeof(f));
    scanf("%d",&n);
    xmax=0;
    for (i=1;i<=n;i++) 
    {
        scanf("%d",&a[i]);
        b[i]=a[i];
        c[a[i]]++;
        xmax=max(xmax,a[i]);
    }
    sort(b+1,b+n+1);
    for (i=1;i<=n;i++) if (b[i]!=b[i-1])
    {
        for (j=1;b[i]*j<=xmax;j++) f[b[i]*j]+=c[b[i]];
    }
    for (i=1;i<=n;i++) printf("%d\n",f[a[i]]-1);
    return 0;
}