Codeforces 359D Pair of Numbers | 二分+ST表+gcd
生活随笔
收集整理的這篇文章主要介紹了
Codeforces 359D Pair of Numbers | 二分+ST表+gcd
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
?題面:
給一個序列,求最長的合法區(qū)間,合法被定義為這個序列的gcd=區(qū)間最小值
輸出最長合法區(qū)間個數(shù),r-l長度
接下來輸出每個合法區(qū)間的左端點
?
題解:
由于區(qū)間gcd滿足單調性,所以我們可以二分區(qū)間長度,用st表維護區(qū)間最小值和gcd即可
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<cmath> 5 #define N 300100 6 using namespace std; 7 int gcd(int x,int y) 8 { 9 return y==0?x:gcd(y,x%y); 10 } 11 int rgcd[N][21],rmin[N][21],n,l,r,mid,ans,ok[N]; 12 int check(int len) 13 { 14 if (len==0) return 1; 15 for (int i=1;i+len<=n;i++) 16 { 17 int tmp=log2(len+1); 18 if (gcd(rgcd[i][tmp],rgcd[i+len-(1<<tmp)+1][tmp]) == min(rmin[i][tmp],rmin[i+len-(1<<tmp)+1][tmp])) 19 return 1; 20 } 21 return 0; 22 } 23 int main() 24 { 25 scanf("%d",&n); 26 for (int i=1,x;i<=n;i++) 27 scanf("%d",&x),rgcd[i][0]=rmin[i][0]=x; 28 for (int j=1;j<=20;j++) 29 for (int i=1;i+(1<<j)-1<=n;i++) 30 rgcd[i][j]=gcd(rgcd[i][j-1],rgcd[i+(1<<j-1)][j-1]),rmin[i][j]=min(rmin[i][j-1],rmin[i+(1<<j-1)][j-1]); 31 r=2*n; 32 while (l<r) 33 { 34 mid=l+r+1>>1; 35 if (check(mid)) 36 l=mid; 37 else r=mid-1; 38 } 39 for (int i=1;i+l<=n;i++) 40 { 41 int tmp=log2(l+1); 42 if (gcd(rgcd[i][tmp],rgcd[i+l-(1<<tmp)+1][tmp]) == min(rmin[i][tmp],rmin[i+l-(1<<tmp)+1][tmp])) 43 ok[i]=1,ans++; 44 } 45 printf("%d %d\n",ans,l); 46 for (int i=1;i<=n;i++) 47 if (ok[i]) printf("%d ",i); 48 return 0; 49 }?
轉載于:https://www.cnblogs.com/mrsheep/p/7880795.html
總結
以上是生活随笔為你收集整理的Codeforces 359D Pair of Numbers | 二分+ST表+gcd的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Oracle 其他数据库对象
- 下一篇: 【探路者】贪吃蛇β发布展示(视频展示)