1. 程式人生 > >BZOJ1607 [Usaco2008 Dec]Patting Heads 輕拍牛頭

BZOJ1607 [Usaco2008 Dec]Patting Heads 輕拍牛頭

題目描述:

今天是貝茜的生日,為了慶祝自己的生日,貝茜邀你來玩一個遊戲. 貝茜讓N(1≤N≤100000)頭奶牛坐成一個圈.除了1號與N號奶牛外,i號奶牛與i-l號和i+l號奶牛相鄰.N號奶牛與1號奶牛相鄰. 農夫約翰用很多紙條裝滿了一個桶,每一張包含了一個獨一無二的1到1,000,000的數字. 接著每一頭奶牛i從柄中取出一張紙條Ai.每頭奶牛輪流走上一圈,同時拍打所有編號能整除在紙條上的數字的牛的頭,然後做回到原來的位置. 牛們希望你幫助他們確定,每一頭奶牛需要拍打的牛.   題解: 類線篩。 由題意可知此題是要求每個數的因子出現次數. 我們將線篩的過程模擬一下,只不過不是篩1~n的所有數,而是隻篩出現過的數。 這樣我們可以篩出每個數的倍數,反過來說就是每個數的因子 我們將相同的數統計一下,在篩倍數的時候加上即可。 不要忘了最後減去自己出現的一次。 附上程式碼:
#include<cstdio>
#include
<cstring> #include<cmath> #include<algorithm> using namespace std; int n,maxx,a[100001],ans[1000001],vis[1000001]; void check(int k) { for(int i=1;i<=k;i++) if(vis[i]) for(int j=i;j<=k;j+=i) ans[j]+=vis[i]; } int main() { scanf("%d"
,&n); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); maxx=max(maxx,a[i]); vis[a[i]]++; } check(maxx); for(int i=1;i<=n;i++) printf("%d\n",ans[a[i]]-1); }