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 那麼我們只需要求最大有多少個區間重疊了就行了,問題就轉化成了區間的修改,單點查詢,可以考慮差分了。注意題目資料 ...