AcWing 201. 可见的点
生活随笔
收集整理的這篇文章主要介紹了
AcWing 201. 可见的点
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
AcWing 201. 可見的點
題意:
題解:
我們先說結論:坐標(i,j),如果i和j互質,說明該坐標為可見
為什么?
我們想想什么樣的坐標可見,什么樣的會被擋住。光線是一個直線,在同一個直線上的點會被第一個點擋住,而所有光都從一個地方出發,也就是如果斜率一樣,后面會被前面的擋住(暫時不考慮斜率不存在的情況)。對于坐標(i,j),斜率為k=i/j,如果i和j不互質,設gcd(i,j)=d,那么(i/d)/(j/d)也等于k,且(i/d,j/d)要比(i,j)小,前者會擋住后綴,這說明了i和j必須互質,不然會被更小的i/d和j/d給擋住
我們觀察題目給的圖形,圖形是關于斜率為1的直線對稱(也很好理解,x與y互質,那y也與x互質),因此我們只考慮下半部分
根據橫坐標,我們依次查看,橫坐標為1時,互質的點的數量為1,橫坐標為2時,互質的數量為1…我們要找的是與橫坐標互質,且小于橫坐標的點的數量,這不就是歐拉函數嗎
所有答案就是橫坐標所對應的歐拉函數的和,乘2(因為我們只算了一半),加1(別忘了對稱軸上還有一個點)
代碼:
#include<bits/stdc++.h> #define debug(a,b) printf("%s = %d\n",a,b); typedef long long ll; using namespace std;inline int read(){int s=0,w=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();//s=(s<<3)+(s<<1)+(ch^48);return s*w; } const int maxn=5e4+9; int prime[maxn],cnt; bool st[maxn]; int phi[maxn]; void init(int n){phi[1]=1;for(int i=2;i<=n;i++){if(!st[i]){prime[cnt++]=i;phi[i]=i-1;}for(int j=0;prime[j]*i<=n;j++){st[prime[j]*i]=1;if(i%prime[j]==0){phi[i*prime[j]]=phi[i]*prime[j];break;}phi[i*prime[j]]=phi[i]*(prime[j]-1);}} } int main() {init(maxn-1);int n,m;cin>>m;for(int T=1;T<=m;T++){cin>>n;int res=1;//對角線那個 for(int i=1;i<=n;i++)res+=phi[i]*2;cout<<T<<" "<<n<<" "<<res<<endl; }return 0; } 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的AcWing 201. 可见的点的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 吉吉王国(二分+树形dp)
- 下一篇: 欧拉函数(简单介绍+例题)