數列問題 二分 思維 好題

2021-08-09 12:19:28 字數 1933 閱讀 3370

description

有兩個數列a,b,求有多少個區間[l,r]使得ma

xri=

lai=

minr

i=lb

i input

第一行為乙個整數 n.

第二行有 n 個整數,表示 a[1]……a[n].

第三行有 n 個整數,表示 b[1]……b[n].

output

輸出乙個整數,表示滿足條件的區間數

sample input

6 1 2 3 2 1 4

6 7 1 2 3 2

sample output

sample explaination

有兩個區間滿足條件,[4,4],[4,5]

我們分析,當區間長度l增大的時候,我們可選擇的數更多,所以ma

x(ai

) 可能更大,mi

n(ai

) 可能更小,也就是說對於任何左端點x,ma

x(ai

) 和mi

n(bi

) 滿足單調性

我們更加深入的分析,即可發現對任意乙個左端點x,有三種情況:

情況一這種情況下一定存在l值滿足條件,所以ans++

但仔細分析,兩線一定只有乙個交點嗎?

不一定,因為l為一段區間的時候可能兩值都相等,如圖

這時我們就可以用二分處理

找出最小滿足ll

eft 的和最大滿足的lr

ight

,然後ans+=lr

ight

-lle

ft+1

情況二在這種情況下兩值任具有單調性,具有相交的趨勢,但是它們在maxlen之前沒有相交,這種情況我們只能同情況一處理,即二分l,然後發現並求不出l的範圍於是ans不改變

情況一和情況二都滿足條件a[x]<b[x],在這種情況下我們可能可以通過擴充套件l使ma

x(ai

) 變大而mi

n(bi

) 變小從而期望在某一點達到相等

情況三這種情況即a[x]>b[x],此時我們發現,擴充套件l只會使ma

x(ai

) 變大mi

n(bi

) 變小,兩值會差的越來越多不可能相交,所以直接跳過就好了

貼機房某大佬的ac**…

#include

#include

#include

#define redir(name) freopen(name".in","r",stdin),freopen(name".out","w",stdout)

using

namespace

std;

inline

char gc()

template

inline

void read(t&n)

const

int n=200010;

int n;

int f[n][21],g[n][21];

inline

void init()

inline

int query1(int l,int r)

inline

int query2(int l,int r)

int main()

if(l==-1) continue;

l=i,r=n;

register

int r=i;

while(l>1;

if(query1(i,mid)>query2(i,mid)) r=mid,r=mid;

else l=mid+1;

}if(query1(i,l)>query2(i,l)) r=l;

ans+=(r-l);

}printf("%lld\n",ans);

return

0;}

IP Filtering hoj 二分好題!!

用位運算將ip轉化成數字。對左端點進行排序。然後將區間合併。最後乙個很蛋疼的地方就是high n 1而不是n,陣列的下標越界。這個地方wa到 啊。左移n,相當於乘以2的n次方,為除 include include include using namespace std struct ip ip 10...

列車排程(思維題,二分查詢)

7 2 列車排程 25 分 火車站的列車排程鐵軌的結構如下圖所示。兩端分別是一條入口 entrance 軌道和一條出口 exit 軌道,它們之間有n條平行的軌道。每趟列車從入口可以選擇任意一條軌道進入,最後從出口離開。在圖中有9趟列車,在入口處按照的順序排隊等待進入。如果要求它們必須按序號遞減的順序...

二分 差分 思維

二分 差分 思維 當猜了乙個數 x 總共有三種情況 裁判說數大了,那麼裁判說對的取值範圍是 x 裁判說數小了,那麼裁判說對的取值範圍是 x,裁判說數一樣,那麼裁判說對的取值範圍是 x,x 那麼我們只需要求最大有多少個區間重疊了就行了,問題就轉化成了區間的修改,單點查詢,可以考慮差分了。注意題目資料 ...