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
【提示】
数据范围与提示:
对于全部数据,1≤N≤105 。
sol:题意有点玄学,对于ai,找出所有 ai%aj==0 的 aj 个数(j≠i)
所以对于一个数ai,对于所有j%i==0的数字有1的贡献,写个像埃氏筛一样的东西就好了
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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 */