日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Codeforces 359D Pair of Numbers | 二分+ST表+gcd

發布時間:2025/4/9 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Codeforces 359D Pair of Numbers | 二分+ST表+gcd 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?題面:

給一個序列,求最長的合法區間,合法被定義為這個序列的gcd=區間最小值

輸出最長合法區間個數,r-l長度

接下來輸出每個合法區間的左端點


?

題解:

由于區間gcd滿足單調性,所以我們可以二分區間長度,用st表維護區間最小值和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的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。