2018南京区域赛 J-Prime Game
生活随笔
收集整理的這篇文章主要介紹了
2018南京区域赛 J-Prime Game
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
完全沒有頭緒
聽完隊友講的我還是楞了好半天菜慢慢理解.我好菜啊
首先要弄懂題目的意思,轉換一下題意就是求每個素因子出現區間的次數.區間長度最短為1.我們分析,第一個數的因子會影響1* n個區間(暫時不考慮重復),第二個數的因子會影響2 * (n-1)個區間,以此類推.因此我們只需要分解每一個數然后加上影響的區間即可.
我們從前往后處理.
可是很容易重復,問題就在于我們如何處理重復的因子.對于位置iii的因子xxx,假設在位置jjj已經出現過,那么對于[j,i?1][j,i-1][j,i?1]的區間是沒有影響的,可是對于以[1,j][1,j][1,j]開頭的區間和以[i,n][i,n][i,n]結尾的區間這個因子就會重復計數,因此為了消去重復,我們給答案減去j?(n?i+1)j*(n-i+1)j?(n?i+1),即會影響區間的個數.對于后面再出現因子xxx的時候,因為jjj對后面的影響已經消去,我們只需要考慮iii對后面的影響,所以同樣進行操作就可以,因此我們記住因子最后出現的位置然后計算即可.
需要注意分解質因數的時候只需要處理到這個數字的開方就可以,如果這個時候這個數還不為1就說明剩下的一定是一個質數就不要進行處理了,否則會超時.
記得開long long ,而且要注意中間會爆long long ,所以在更新ans的時候要小心.
#include<cstdio> #include<cstring> #include<algorithm> #include<climits> #include<cctype> #include<queue> #include<set> #include<cmath>using namespace std;typedef long long ll; const int INF=0x3f3f3f3f; const int MAXN=1e6+5; const int MAXM=1e6+5;int check[MAXM]; int prime[MAXM]; int vis[MAXM]; int tot=0; int n,x; ll ans;void creat_prime() {for(int i=2;i<MAXN;i++){if(!check[i]) prime[tot++]=i;for(int j=0;j<tot && prime[j]*i<MAXN;j++){check[prime[j]*i]=true;if(i%prime[j]==0) break;}} }void deal(int x,int idx) {int t=sqrt(x)+1;for(int i=0;i<tot && prime[i]<=t;i++){if(x%prime[i]==0){ans+=(ll)idx*(n-idx+1);if(vis[prime[i]]==0) vis[prime[i]]=idx;else{ans-=(ll)vis[prime[i]]*(n-idx+1);vis[prime[i]]=idx;}while(x%prime[i]==0){x/=prime[i];}}if(x==1) break;}if(x>1){ans+=(ll)idx*(n-idx+1);if(vis[x]==0) vis[x]=idx;else{ans-=(ll)vis[x]*(n-idx+1);vis[x]=idx;}} }int main() {creat_prime();scanf("%d",&n);ans=0;for(int i=1;i<=n;i++){scanf("%d",&x);deal(x,i);}printf("%lld\n",ans);return 0; }總結
以上是生活随笔為你收集整理的2018南京区域赛 J-Prime Game的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 成都大熊猫繁育基地几号线
- 下一篇: HDU - 2973威尔逊定理