題幹:
小a有乙個長度為nn的排列。定義一段區間是"萌"的,當且僅當把區間中各個數排序後相鄰元素的差為11
現在他想知道包含數x,yx,y的長度最小的"萌"區間的左右端點
也就是說,我們需要找到長度最小的區間[l,r][l,r],滿足區間[l,r][l,r]是"萌"的,且同時包含數xx和數yy
如果有多個合法的區間,輸出左端點最靠左的方案。
第一行三個整數n,x,yn,x,y,分別表示序列長度,詢問的兩個數第二行有nn個整數表示序列內的元素,保證輸入為乙個排列
輸出兩個整數,表示長度最小"萌"區間的左右端點示例1
複製
5 2 3複製5 2 1 3 4
2 4
區間[2,4]=[2,4]=包含了2,32,3且為「萌」區間,可以證明沒有比這更優的方案示例2
複製
8 3 5複製6 7 1 8 5 2 4 3
5 8
保證2⩽n⩽105,1⩽x,y⩽n解題報告:
這題首先可以證明合法的區間是唯一的,並不存在題中說的多個合法區間。然後某個區間是我們需要的 當且僅當 這個區間的長度 == 這段區間內最大值和最小值的差,也就是maxx - minn == r - l。如果不滿足,那就要將區間往外擴張,擴張到哪呢?當然是這些數**現的最左端的和最右端的。同時可以證明這樣迴圈最終一定有界(也就是一定是收斂的),因為最差情況就是擴充套件到整個區間,一定滿足條件唄。這樣一步步模擬最終得出答案。
ac**:
#include#include#include#include#include#include#include#include#include#include#define ll long long
#define pb push_back
#define pm make_pair
#define fi first
#define se second
using namespace std;
const int max = 2e5 + 6;
const int inf = 0x3f3f3f3f;
int a[max],pos[max];
int main()
int l = pos[x],r = pos[y];
int maxx = -inf,minn = inf;
if(l>r) swap(l,r);
for(int i = l; i<=r; i++) minn = min(minn,a[i]),maxx = max(maxx,a[i]);
while(r-l != maxx - minn)
printf("%d %d\n",l,r);
return 0 ;
}
區間逼近 牛客寒假1 小a的排列
做法 模擬 萌區間也就是這個區間裡的數是一段連續的數 做法的話是先找出題目x,y的位置,記為l,r,然後找出l,r內的最大最小值,又因為萌區間要求數是連續的,就從這段連續數最小的開始到最大的,確定縮放區間的左右端點,但現在這個縮放區間可能還包含有別的區間,我們就開始拓展拓展答案區間 主要是要注意兩點...
牛客寒假演算法基礎集訓營1 G 小a的排列 思維
這道題在比賽的時候思路已經想出來了,但是沒有實現出來.首先我們要知道乙個區間要滿足 萌 的條件必須是23456這樣的子串,那麼對於2356這樣的子串我們就需要去找4,所以我們可以知道 萌 的條件就是l r max min 區間長度等於區間內的最大值減最小值 那麼我們先在l到r的區間中求出最大值和最小...
牛客 小G的約數引起的對於 整數分塊 學習
整除分塊是個啥 要求 n 的值,這時候暴力需要o n 的時間。由於這個區間是連續的,且 是向下取整,當i不能整除k時,n i會等於最小的i 也就是區間最左邊的值 l 除n的商。此時如果可以很快的找到這乙個區間,那麼就可以將時間複雜度降到 o sqrt 接下來講一下怎麼去找這個區間 假設n 20,然後...