bzoj 4921: [Lydsy六月月赛]互质序列
生活随笔
收集整理的這篇文章主要介紹了
bzoj 4921: [Lydsy六月月赛]互质序列
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
4921: [Lydsy六月月賽]互質序列
Time Limit:?1 Sec??Memory Limit:?256 MBSubmit:?188??Solved:?110
[Submit][Status][Discuss]
Description
你知道什么是“互質序列”嗎?那就是所有數的最大公約數恰好為1的序列。 “互質序列”非常容易找到,但是我們可以嘗試通過刪除這個序列的一個非空連續子序列來擴大它的最大公約數。 現在給定一個長度為n的序列,你需要從中刪除一個非空連續子序列,使得剩下至少2個數,令E為剩下數的最大公約數的期望值,S為合法的方案數,請計算E*S的值。因為這個值可能非常大,請對998244353取模輸出。Input
第一行包含一個正整數n(3<=n<=100000),表示序列的長度。 第二行包含n個正整數a_1,a_2,...,a_n(1<=a_i<=10^9),分別表示序列中的每個元素。Output
輸出一行一個整數,即E*S mod 998244353的值。Sample Input
53 4 5 2 9
Sample Output
14發現本質就是選一個前綴(可以為空)和一個后綴(可以為空),使得前綴的末尾必須在后綴的開頭的左邊且不能相鄰且前綴后綴元素個數>=2的前后綴gcd的和。 可以發現每個后綴的gcd都是a[n]的某個約數,并且gcd最多只有log種,因為每次gcd減小都伴隨著至少一個質因子的失去。 所以我們就可以寫暴力了,設r[i]為與i的后綴有相同gcd的最右后綴j,每次暴力統計就好了。 反正我是分成只有前綴(這時候不能只選a[1]),只有后綴(不能只選a[n]),還有前綴后綴都有的情況。 /**************************************************************Problem: 4921User: JYYHHLanguage: C++Result: AcceptedTime:308 msMemory:2460 kb ****************************************************************/#include<bits/stdc++.h> #define ll long long #define maxn 100005 const int ha=998244353; using namespace std; int a[maxn],n,hz[maxn]; int r[maxn],qz=0,ans=0;inline int add(int x,int y){x+=y;while(x>=ha) x-=ha;return x; }int gcd(int x,int y){return y?gcd(y,x%y):x; }int main(){scanf("%d",&n);for(int i=1;i<=n;i++) scanf("%d",a+i);hz[n+1]=0;for(int i=n;i>1;i--){hz[i]=gcd(a[i],hz[i+1]);r[i]=(hz[i]==hz[i+1]?r[i+1]:i);//后綴 if(i<n) ans=add(ans,hz[i]);}for(int i=1;i<n;i++){qz=gcd(qz,a[i]);//前綴 if(i>1) ans=add(ans,qz);//前綴+后綴 if(qz==1) ans=add(ans,n-i-1);else{for(int j=i+2;j<=n;j=r[j]+1){ans=add(ans,gcd(hz[j],qz)*(ll)(r[j]-j+1)%ha);}}}printf("%d\n",ans);return 0; }
轉載于:https://www.cnblogs.com/JYYHH/p/8525848.html
總結
以上是生活随笔為你收集整理的bzoj 4921: [Lydsy六月月赛]互质序列的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: centos08-Linux服务器上发布
- 下一篇: 强迫症犯了,忍不住赞一下slf4j包Lo