做法:模擬
萌區間也就是這個區間裡的數是一段連續的數
做法的話是先找出題目x,y的位置,記為l,r,然後找出l,r內的最大最小值,又因為萌區間要求數是連續的,就從這段連續數最小的開始到最大的,確定縮放區間的左右端點,但現在這個縮放區間可能還包含有別的區間,我們就開始拓展拓展答案區間
主要是要注意兩點,首先這個序列是個排列(所以它不會有重複數字出現),於是由這個我們可以推出乙個顯然的結論就是r−l
=max
[l,r
]−mi
n[l,
r]'>r−l=max[l,r]−min[l,r]
r−l=max[l,r]−min[l,r]時這是個連續區間。
然後我們處理出每個數字出現的位置,於是可以求出第乙個可能滿足題目要求的區間,記為[ql
,qr]
'>[ql,qr]
[ql,qr],並儲存這個區間的最大最小值。
(為什麼是可能呢?因為你現在只求出了x到y之間的數所需要的最短的區間,但是你並不知道這個區間裡有沒有其他不應該有的數字,讓這個區間變得真正合法,就是我們下面要做的事情)
設每個數出現的位置為pos
'>pos
pos。
我們可以將原始區間記為[l,
r]'>[l,r]
[l,r](即一開始的[po
s[x]
,pos
[y]]
'>[pos[x],pos[y]]
[pos[x],pos[y]])。
嘗試不斷拓展這個區間[l,
r]'>[l,r]
[l,r],在拓展過程中如果出現了大於最大值,或者小於最小值的,就用一開始處理[ql
,qr]
'>[ql,qr]
[ql,qr]的方法更新[ql
,qr]
'>[ql,qr]
[ql,qr]。直至兩區間重合。那麼此時的[l,
r]'>[l,r]
[l,r]即為答案了。
這樣做是o(n
)'>o(n)
o(n)的,不過常數可能稍大,因為會有重複訪問。
寫了rmq的話就可以穩定o(n
)'>o(n)
o(n)了(不過預處理要o(n
logn
)'>o(nlogn)
o(nlogn),所以大概實際效率上是沒什麼大的區別的)
#include usingnamespace
std;
const
int inf=1
<<30
;typedef
long
long
ll;const
double pi=acos(-1
);const
int mod=1e9+7
;const
int maxn=1e5+7
;int
a[maxn],pos[maxn];
intmain()
int ql=n,qr=1,l=pos[x],r=pos[y];
if(l>r) swap(l,r);//
這點特別容易錯,要當心
for(int i=l;i<=r;i++)
for(int i=mn;i<=mx;i++)
//此時找出的左右端點一定不小於我們要找的答案,其中可能會包含有其他數
while(l!=ql || r!=qr)
while(mn>t)
}while(r!=qr)
while(mn>t)}}
cout
<"
"return0;
}
牛客寒假演算法基礎集訓營1 G 小a的排列 思維
這道題在比賽的時候思路已經想出來了,但是沒有實現出來.首先我們要知道乙個區間要滿足 萌 的條件必須是23456這樣的子串,那麼對於2356這樣的子串我們就需要去找4,所以我們可以知道 萌 的條件就是l r max min 區間長度等於區間內的最大值減最小值 那麼我們先在l到r的區間中求出最大值和最小...
題解 牛客寒假訓練賽1
牛客寒假訓練賽1,自己水平還是太差了。a 題意 有計算符號和結果,求最初的數 思路 簡單模擬 include define ll long long struct note a 101 int main printf lld k return 0 b 給定2,0,4的數量,對其進行排列,計算1 i的...
2020牛客寒假集訓營1
b.kotori和bangdream 大水題 include include include include include include include include include include define ll long long const int n 1e6 10 using na...