【问题描述】
话说自从欧教给乐乐发了一个棒棒糖之后,机房的众基友就心理不平衡了。于是欧教不得不买了很多糖准备发给众基友。
但是新的问题出现了:每个基友都想得到更多的糖,因此平均分配的原则在这里根本行不通。于是欧教又在网上找了一套呵呵难度的题并出了相当坑爹的数据,以考试的成绩来作
为发糖的标准。
当然,欧教的发糖标准也非常奇葩:对于基友A,如果在其他基友中有t 个人的得分是A 得分的因数,则就给A 发t 个糖。
现在,欧教已经测出了每个基友的得分,他想知道每个基友能得到多少颗糖。
【输入数据】
第一行一个整数n,表示机房一共有n 个基友。
接下来共n 行,每行一个整数Bi 表示第i 个人的得分。
【输出数据】
共 n 行,第i 行表示第i 人得到的糖数。
【样例输入】
2
2
2
【样例输出】
1
1
【数据范围及约定】
1≤n≤100000;
1≤Bi≤1000000。
此题考察筛选法的应用。用一个cnt数组记录每个结点包含自身的约数个数,然后用筛选法的思想,每次用当前的数去筛比它大的所有数(当然被筛的数必定是这个数的倍数),最后输出时排除掉自身即可。
另外在筛的时候,先将所有的数排序可以更快(将所有相同的数放在一起筛)。
Accode:
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <string>
const int maxN = 100010, maxP = 1000010;
int cnt[maxP], a[maxN], c[maxN], n, Lim;
inline int getint()
{
int res = 0; char tmp;
while (!isdigit(tmp = getchar()));
do res = (res << 3) + (res << 1) + tmp - '0';
while (isdigit(tmp = getchar()));
return res;
}
int main()
{
freopen("candy.in", "r", stdin);
freopen("candy.out", "w", stdout);
n = getint();
for (int i = 0; i < n; ++i)
Lim = std::max(Lim, a[i] = c[i] = getint());
std::sort(c, c + n);
for (int i = 0; i < n; ++i)
{
int tot = 1;
while (c[i] == c[i + 1])
++tot, ++cnt[c[i++]];
++cnt[c[i]];
for (int tmp = c[i] << 1; tmp
< Lim + 1; tmp += c[i])
cnt[tmp] += tot;
}
for (int i = 0; i < n; ++i)
printf("%d\n", cnt[a[i]] - 1);
return 0;
}