题目描述
原题来自:USACO 2008 Dec. Silver
今天是 Bessie 的生日,并且现在是聚会的游戏时间。Bessie 让编号为 1∼N1\sim N1∼N 的 NNN 头奶牛围成一个圈坐(所以除了最后一头牛,第 iii 头奶牛与第 i−1i-1i−1 和 i+1i+1i+1 头奶牛相邻,第 NNN 头奶牛和第 N−1N-1N−1 头与第 111 头奶牛相邻)。同时,Farmer John 拿了个桶,在桶里装了十亿张小纸条,每张小纸条上写有某个范围在 [1,106][1,10^6][1,106] 的整数。
接着,每头奶牛轮流从这个巨桶中抽取一个数 Ai (1≤Ai≤106)A_i\ (1\le A_i\le 10^6)Ai (1≤Ai≤106)(当然这些数没必要两两不同)。然后第 iii 头奶牛走一圈,如果奶牛 iii 手中的数字能够被奶牛 j(j≠i)j(j\neq i)j(j=i) 手中的数字整除,那么奶牛 iii 会拍奶牛 jjj 的头。走完一圈后,奶牛 iii 回到原来的位置。
奶牛们想让你帮他们计算,对于每头奶牛,它需要拍多少头奶牛的头?
输入格式
第一行包含一个整数 NNN;
接下来第二到第 N+1N+1N+1 行每行包含一个整数 AiA_iAi。
输出格式
第一到第 NNN 行,第 iii 行的输出表示第 iii 头奶牛要拍打的牛数量。
样例
Input | Output |
---|---|
5 2 1 2 3 4 | 2 0 2 1 3 |
第一头奶牛会拍第二、第三头奶牛,第二头牛不会拍任何奶牛的头,等等。
数据范围与提示
对于全部数据,1≤N≤1051\le N\le 10^51≤N≤105。
解析:要注意每个数出现的次数,有可能出现重复的数,不做重复处理。找出输入的所有数中的最大数,之后遍历每一个数,每个数小于最大数并且出现次数就为这个数的答案,并且由这个数向他的倍数延申。
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int a[N],s[N],book[N];
int main()
{
int m,maxx=0,i,t;
scanf("%d",&m);
for(i=0;i<m;i++)
{
scanf("%d",&a[i]),
book[a[i]]++;
if(maxx<a[i])
maxx=a[i];
}
for(i=0;i<m;i++)
if(book[a[i]])
{
t=a[i];
while(t<=maxx)
{
s[t]+=book[a[i]];
t+=a[i];
}
book[a[i]]=0;
}
for(i=0;i<m;i++)
printf("%d\n",s[a[i]]-1);
return 0;
}