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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

CF5E-Bindian Signalizing【单调栈】

發(fā)布時(shí)間:2023/12/3 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CF5E-Bindian Signalizing【单调栈】 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

正題

題目鏈接:https://www.luogu.com.cn/problem/CF5E


題目大意

圓上有nnn個(gè)山,兩個(gè)山之間可以看到當(dāng)且僅當(dāng)它們之間的兩條弧中有一條滿(mǎn)足所有山都不高于它們兩個(gè)。

求可以看到的山的對(duì)數(shù)。

3≤n≤106,1≤hi≤1093\leq n\leq 10^6,1\leq h_i\leq 10^93n106,1hi?109


解題思路

先找到最高的山,然后先考慮它之外的點(diǎn)對(duì)再考慮這座山的貢獻(xiàn),因?yàn)檫@樣矮的點(diǎn)之間肯定有一座高山擋著。

然后前后各維護(hù)一個(gè)單調(diào)隊(duì)列,每個(gè)元素被彈出的時(shí)候就會(huì)統(tǒng)計(jì)一個(gè)點(diǎn)對(duì)。

然后考慮相同的情況,對(duì)于前后中的一個(gè)做的時(shí)候,彈完之后在單調(diào)隊(duì)列上二分相同的位置即可。

時(shí)間復(fù)雜度O(nlog?n)O(n\log n)O(nlogn)


code

#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=1e6+10; int n,m,mx,top,a[N],b[N],s[N],v[N]; long long ans; int main() {scanf("%d",&m);mx=1;for(int i=1;i<=m;i++){scanf("%d",&b[i]);if(b[i]>b[mx])mx=i;}for(int i=mx+1;i<=m;i++)a[++n]=b[i];for(int i=1;i<mx;i++)a[++n]=b[i];for(int i=1;i<=n;i++){while(top>0&&a[s[top]]<a[i])top--,ans++;int l=1,r=top;while(l<=r){int mid=(l+r)>>1;if(a[s[mid]]==a[i])r=mid-1;else l=mid+1;}ans+=top-r;s[++top]=i;}top=0;for(int i=n;i>=1;i--){while(top>0&&a[s[top]]<a[i])top--,ans++;s[++top]=i;}for(int i=1,z=0;i<=n;i++)if(a[i]>=z)z=a[i],ans+=!v[i],v[i]=1;for(int i=n,z=0;i>=1;i--)if(a[i]>=z)z=a[i],ans+=!v[i],v[i]=1;printf("%lld\n",ans);return 0; }

總結(jié)

以上是生活随笔為你收集整理的CF5E-Bindian Signalizing【单调栈】的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。