题目描述
今天是贝茜的生日,为了庆祝自己的生日,贝茜邀你来玩一个游戏。
贝茜让 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;
}