一本通1621轻拍牛头

1621:轻拍牛头

时间限制: 1000 ms         内存限制: 524288 KB

【题目描述】

原题来自:USACO 2008 Dec. Silver

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

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

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

【输入】

第一行包含一个整数 N;

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

【输出】

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

【输入样例】

5
2
1
2
3
4

【输出样例】

2
0
2
1
3

【提示】

数据范围与提示:

对于全部数据,1N105 。

 

sol:题意有点玄学,对于ai,找出所有 ai%aj==0 的 aj 个数(j≠i)

所以对于一个数ai,对于所有j%i==0的数字有1的贡献,写个像埃氏筛一样的东西就好了

#include <bits/stdc++.h>
using namespace std;
typedef int ll;
inline ll read()
{
    ll s=0;
    bool f=0;
    char ch=' ';
    while(!isdigit(ch))
    {
        f|=(ch=='-'); ch=getchar();
    }
    while(isdigit(ch))
    {
        s=(s<<3)+(s<<1)+(ch^48); ch=getchar();
    }
    return (f)?(-s):(s);
}
#define R(x) x=read()
inline void write(ll x)
{
    if(x<0)
    {
        putchar('-'); x=-x;
    }
    if(x<10)
    {
        putchar(x+'0'); return;
    }
    write(x/10);
    putchar((x%10)+'0');
    return;
}
#define W(x) write(x),putchar(' ')
#define Wl(x) write(x),putchar('\n')
const int N=100005,B=1000005;
int n,a[N];
int Ges[B],ans[B];
int main()
{
    int i,j,m=0;
    R(n);
    for(i=1;i<=n;i++)
    {
        m=max(m,a[i]=read());
        Ges[a[i]]++;
    }
    for(i=1;i<=m;i++) if(Ges[i])
    {
        for(j=i;j<=m;j+=i) ans[j]+=Ges[i];
    }
    for(i=1;i<=n;i++)
    {
        Wl(ans[a[i]]-1);
    }
    return 0;
}
/*
input
5
2
1
2
3
4
output
2
0
2
1
3
*/
View Code

 

posted @ 2019-02-24 11:53  yccdu  阅读(591)  评论(0编辑  收藏  举报