筛-BZOJ-1607-[Usaco2008 Dec]Patting Heads 轻拍牛头

Description
今天是贝茜的生日,为了庆祝自己的生日,贝茜邀你来玩一个游戏.
贝茜让N(1≤N≤100000)头奶牛坐成一个圈.除了1号与N号奶牛外,i号奶牛与i-l号和i+l号奶牛相邻.N号奶牛与1号奶牛相邻.农夫约翰用很多纸条装满了一个桶,每一张包含了一个独一无二的1到1,000,000的数字.
接着每一头奶牛i从柄中取出一张纸条Ai.每头奶牛轮流走上一圈,同时拍打所有编号能整除在纸条上的数字的牛的头,然后做回到原来的位置.牛们希望你帮助他们确定,每一头奶牛需要拍打的牛.
Input
第1行包含一个整数N,接下来第2到N+1行每行包含一个整数Ai.
Output

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

Sample Input
5 //有五个数,对于任一个数来说,其它的数有多少个是它的约数

2

1

2

3

4

INPUT DETAILS:

The 5 cows are given the numbers 2, 1, 2, 3, and 4, respectively.

Sample Output
2

0

2

1

3

OUTPUT DETAILS:

The first cow pats the second and third cows; the second cows pats no cows;

etc.

题解:
直接线性筛的思路,把out[i*k]都加上num[i],最后别忘记要记得减一(i本身自己那个一)。
我这里加了一个输入科技,kb菊苣的模板。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <utility>
#include <cstdlib>
#include <algorithm>
#define MAXN 100005
#define MAX 1000005
using namespace std;
long long int num[MAX],a[MAXN],out[MAX],x=0,tmp,n;
template <class T>
inline bool scan_d(T &ret)
{
    char c;
    int sgn;
    if(c=getchar(),c==EOF) return 0; //EOF
    while(c!='-'&&(c<'0'||c>'9')) c=getchar();
    sgn=(c=='-')?-1:1;
    ret=(c=='-')?0:(c-'0');
    while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');
    ret*=sgn;
    return 1;
}
int main(int argc, const char * argv[])
{
    scan_d(n);
    for(long long int i=1; i<=n; i++)
    {
        scan_d(a[i]);
        x=max(x,a[i]);
        num[a[i]]++;
    }
    for(long long int i=1; i<=x; i++)
    {
        if(num[i])
            for(long long int j=i; j<=x; j+=i)
                out[j]+=num[i];
    }
    for(long long int i=1; i<=n; i++)
        printf("%lld\n",out[a[i]]-1);
    return 0;
}

你可能感兴趣的:(ACM)