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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

牛客练习赛69E-子串【树状数组】

發布時間:2023/12/3 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 牛客练习赛69E-子串【树状数组】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

正題

題目鏈接:https://ac.nowcoder.com/acm/contest/7329/E


題目大意

給出一個nnn的排列,求有多少個區間[l,r][l,r][l,r]使得最大值是rrr,最小值是lll


解題思路

首先對于一個位置的值作為左端點和右端點都有一段合法區間(到左邊第一個比他小的和右邊第一個比他大的,當右端點時同理)。可以用樹狀數組預處理每個的合法區間

然后對于兩個點各作為左右端點需要滿足左端點在右端點的合法區間內,右端點在左端點的合法區間內。

那么有算法就是對于每個右端點我們在他合法區間的左邊壓入,右邊彈出然后指針掃描作為左端點的值進行區間查詢即可。

時間復雜度O(nlog?n)O(n\log n)O(nlogn)


codecodecode

#include<cstdio> #include<cstring> #include<algorithm> #include<vector> #define lowbit(x) (x&-x) using namespace std; const int N=1e6+10; int n,p[N],la[N],ra[N],lp[N],rp[N],num[N]; vector<int> ql[N],qr[N]; long long ans; struct Tree_Array{int t[N];void Change(int x,int val){while(x<=n){t[x]=max(val,t[x]);x+=lowbit(x);}return;}int Ask(int x){int ans=0;while(x){ans=max(t[x],ans);x-=lowbit(x);}return ans;} }Ta,Tp; struct tTree_Array{int t[N];void Change(int x,int val){while(x<=n){t[x]+=val;x+=lowbit(x);}return;}int Ask(int x){int ans=0;while(x){ans+=t[x];x-=lowbit(x);}return ans;} }T; bool cmp(int x,int y) {return p[x]<p[y];} int main() {scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d",&p[i]),num[i]=i;for(int i=1;i<=n;i++){la[i]=Ta.Ask(p[i]);ra[i]=Tp.Ask(n-p[i]+1);Ta.Change(p[i],i);Tp.Change(n-p[i]+1,i);}memset(Ta.t,0,sizeof(Ta.t));memset(Tp.t,0,sizeof(Tp.t));for(int i=n;i>=1;i--){lp[i]=n-Ta.Ask(p[i])+1;rp[i]=n-Tp.Ask(n-p[i]+1)+1;Ta.Change(p[i],n-i+1);Tp.Change(n-p[i]+1,n-i+1);}for(int i=1;i<=n;i++)if(p[i]>=i&&ra[i]<p[i]&&p[i]<rp[i]){ql[ra[i]].push_back(i);qr[rp[i]].push_back(i);}sort(num+1,num+1+n,cmp);for(int i=0;i<=n;i++){int x=num[i];for(int j=0;j<qr[i].size();j++)T.Change(p[qr[i][j]],-1);if(p[x]<=x&&la[x]<p[x]&&p[x]<lp[x])ans+=T.Ask(lp[x]-1)-T.Ask(x-1);for(int j=0;j<ql[i].size();j++)T.Change(p[ql[i][j]],1);}printf("%lld",ans); }

總結

以上是生活随笔為你收集整理的牛客练习赛69E-子串【树状数组】的全部內容,希望文章能夠幫你解決所遇到的問題。

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