轻拍牛头(类埃式筛)
今天是贝茜的生日,为了庆祝自己的生日,贝茜邀你来玩一个游戏。
贝茜让 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
【提示】
数据范围与提示:
对于全部数据,1≤N≤105 。
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; }