RMQ问题:与众不同(st表的高端应用)
生活随笔
收集整理的這篇文章主要介紹了
RMQ问题:与众不同(st表的高端应用)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
解析
預處理
用pre[i]表示以i結尾的最長完美序列起始點,用last[i]表示數(shù)字i最后出現(xiàn)的位置
那么可以得到遞推式:
也就是說這個pre要么是受前一位一樣的限制,要么是受自己的限制
用f[i]表示以i結尾的最長完美序列長度,那么顯然:
以上可以用O(n)完成預處理
詢問
接下來對于每次詢問區(qū)間 [l,r] 中的每一位,只有兩種可能:
1.pre在l左側或l上
2.pre在l右側
根據(jù)之前的遞推式,pre顯然單調不減。
因此這兩種情況的分布具有單調性,我們就可以二分找出一個結點mid,使左側及本身的pre均<=l(稱為A),右側pre均>l(稱為B)
A:對于A的每一個元素,其在區(qū)間內可以達到的長度應該為i-l+1;那么顯然讓i=A中最大的值——mid時,取到最大值
B:對與B中的每一個元素,以其結尾的最大長度就是f[i],因此B的最優(yōu)就是f在[now+1,r]中的最大值,用st表維護即可
A和B各自的最優(yōu)取max,就是答案
單次詢問時間復雜度O(logn)
代碼
#include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <iostream> #include <string> #include <queue> #include <string> #include<map> #define ll long long #define mem(a,b) memset(a,b,sizeof(a)); using namespace std; const int N=2e5+100; const int M=2e6+100; int n,m,mod,ask; int a,b,c; int x[N],pre[N],last[M],f[N]; int dp[N][30],q[N]; int maxx(int a,int b){int k=q[(b-a)+1];int ans=max(dp[a][k],dp[b-(1<<k)+1][k]);return ans; } void Dp(){int o=0;for(int i=1;i<=n;i++){if(1<<o<=i) o++;q[i]=o-1;}for(int i=1;i<=n;i++) dp[i][0]=f[i];for(int k=1;k<=q[n];k++){for(int i=1;i+(1<<k)-1<=n;i++) dp[i][k]=max(dp[i][k-1],dp[i+(1<<(k-1))][k-1]);} } int find(int l,int r){int st=l,ed=r;while(st<ed){int mid=(st+ed+1)>>1;if(pre[mid]<=l) st=mid;else ed=mid-1;}return st; } int query(int l,int r){int now=find(l,r);int ans=now-l+1; // int ans=0; // for(int i=l;i<=r;i++){ // if(pre[i]<=l) ans=max(ans,i-l+1); // else ans=max(ans,f[i]); // }//ans=max(ans,maxx(now+1,r)); // for(int i=now+1;i<=r;i++) ans=max(ans,f[i]);ans=max(ans,maxx(now+1,r));return ans; } void read(){scanf("%d%d",&n,&m);for(int i=1;i<=n;i++) scanf("%d",&x[i]); } void solve(){for(int i=1;i<=n;i++){pre[i]=max(pre[i-1],last[x[i]]+1);last[x[i]]=i;f[i]=i-pre[i]+1; // printf("%d ",pre[i]);} // printf("\n");Dp(); } void putout(){for(int i=1;i<=m;i++){scanf("%d%d",&a,&b);a++;b++;if(pre[b]<=a){printf("%d\n",b-a+1);continue;}printf("%d\n",query(a,b));} } int main(){read();solve();putout();return 0; } /* 9 15 1 2 3 4 5 6 7 8 9 */疑問
仔細看代碼的童鞋會發(fā)現(xiàn)我的數(shù)組都開了2e6,但除了last之外應該開到2e5(n的范圍)就夠了
但一開始開2e5wa掉了。。。
期待看破其中玄機的dl評論區(qū)指點迷津awa
謝謝!
總結
以上是生活随笔為你收集整理的RMQ问题:与众不同(st表的高端应用)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 花旗银行称“退出中国市场”不属实
- 下一篇: 模板:高精