轻拍牛头(类埃式筛)

题目链接

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

贝茜让 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的贡献,写个像埃氏筛一样的东西就好了

#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
#include<cstring>
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
template <typename Tp>
void read(Tp &x){//read(n);
    x=0;char ch=1;int fh;
    while(ch!='-'&&(ch>'9'||ch<'0')){
        ch=getchar();
    }
    if(ch=='-'){
        fh=-1;ch=getchar();
    }else fh=1;
    while(ch>='0'&&ch<='9'){
        x=(x<<1)+(x<<3)+ch-'0';ch=getchar();
    }
    x*=fh;
}
inline char read1()//字符串读入挂
{
    register char ch=getchar();
    while(ch<'A'||ch>'M')ch=getchar();
    return ch;
}
const int maxn=1e6+100;
int a[maxn];
int vis[maxn];
int ans[maxn];
int main(){
    int n;
    cin>>n;
    int ma=0;
    for(int i=1;i<=n;i++){
        read(a[i]);
        vis[a[i]]++;
        ma=max(ma,a[i]);
    }
    for(int i=1;i<=ma;i++){
        if(vis[i]){
            for(int j=i;j<=ma;j+=i){
                ans[j]+=vis[i];    
            }
        }
    }
    for(int i=1;i<=n;i++){
        cout<<ans[a[i]]-1<<endl;
    }
    cout<<endl;
} 

 

posted @ 2020-09-24 21:42  哎呦哎(iui)  阅读(150)  评论(0编辑  收藏  举报