题目描述

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

贝茜让 N 头奶牛坐成一个圈。除了 1 号与 N 号奶牛外,i 号奶牛与i−1 号和 i+1 号奶牛相邻,N 号奶牛与 1 号奶牛相邻。农夫约翰用很多纸条装满了一个桶,每一张包含了一个 1 到 106 的数字。

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

输入

第一行包含一个整数 N;

接下来第二到第 N+1 行每行包含一个整数 Ai。

对于全部数据,1≤N≤105。

输出

第一到第 N 行,第 i 行的输出表示第 i 头奶牛要拍打的牛数量。

样例输入

5

2

1

2

3

4

样例输出

2

0

2

1

3

思路:

我们可以存下所有数出现的次数,然后将所有他们的倍数加上他们的个数,最后记得减去一次自己重复加上的即可(这道题对时间复杂度要求挺高,暴力肯定过不了,哪怕是这串代码,也被卡cin)

代码:

#include<bits/stdc++.h>

using namespace std;

const int M=1e7+5;

int a[M],v[M]={0},ans[M];

int main()

{

int n;

scanf("%d",&n);

int max1=0;//找出最大数

for(int i=1;i<=n;i++)

{

scanf("%d",&a[i]);

v[a[i]]++;//当前该数出现次数

max1=max(max1,a[i]);

}

for(int i=1;i<=max1;i++)

{

if(!v[i])

continue;

for(int j=i;j<=max1;j=j+i)//如果是i的倍数,则加上i的次数

{

ans[j]+=v[i];

}

}

for(int i=1;i<=n;i++)

{

printf("%d\n",ans[a[i]]-1);

}

return 0;

}