time limit: 40 sec memory limit: 256 mb
joi村有一片荒地,上面豎著n個稻草人,村民們每年多次在稻草人們的周圍舉行祭典。
有一次,joi村的村長聽到了稻草人們的啟示,計畫在荒地中開墾一片田地。和啟示中的一樣,田地需要滿足以下條件:
田地的形狀是邊平行於座標軸的長方形;
左下角和右上角各有乙個稻草人;
田地的內部(不包括邊界)沒有稻草人。
給出每個稻草人的座標,請你求出有多少遵從啟示的田地的個數
第一行乙個正整數n,代表稻草人的個數
接下來n行,第i行(1<=i<=n)包含2個由空格分隔的整數xi和yi,表示第i個稻草人的座標
輸出一行乙個正整數,代表遵從啟示的田地的個數
40 0
2 23 4
4 33
所有滿足要求的田地由下圖所示:
1<=n<=2*10^5
0<=xi<=10^9(1<=i<=n)
0<=yi<=10^9(1<=i<=n)
xi(1<=i<=n)互不相同。
yi(1<=i<=n)互不相同。
先將x軸排序,然後cdq分治,這樣先保證左面x值一定小於右面
然後兩邊分別按y軸排序,然後去找合法解
我們可以左面維護x單調遞增的棧,右面維護x單調遞減的棧,這樣對於左面的每一位在右面二分查詢就好
#include#include#include
#include
#include
#include
#include
using
namespace
std;
#define inf 1000000007
#define ll long long
#define n 200010inline
intrd()
while(ch>='
0'&&ch<='9')
return x*f;
}int
n;ll ans;
struct qaza[n],b[n];
bool cmp(qaz a,qaz b)
intq1[n],q2[n];
int fd(int x,int l,int
r)
returnl;}
void cdq(int l,int
r) ans+=t2-fd(a[q1[t1-1]].y,0,t2+1
); }
for(i=l,t1=l,t2=mid+1;i<=r;i++) b[i]=((t1<=mid&&a[t1].yr)?a[t1++]:a[t2++];
for(i=l;i<=r;i++) a[i]=b[i];
}int
main()
BZOJ4237 稻草人 CDQ分治
joi村有一片荒地,上面豎著n個稻草人,村民們每年多次在稻草人們的周圍舉行祭典。有一次,joi村的村長聽到了稻草人們的啟示,計畫在荒地中開墾一片田地。和啟示中的一樣,田地需要滿足以下條件 田地的形狀是邊平行於座標軸的長方形 左下角和右上角各有乙個稻草人 田地的內部 不包括邊界 沒有稻草人。給出每個稻...
BZOJ 4237 稻草人 分治
分治。1.按y軸排序 2.分治處理 l,mid 和 mid 1,r 計算 l,mid 能對 mid 1,r 部分作出的貢獻 隨便花乙個圖發現上半部分維護y值遞增的單調棧下半部分維護y單調減得單調棧,這樣下半部分棧中元素都是可以和上半部分配對不會出現包括的情況,但是x座標必須大於s1 t1 1 就是第...
BZOJ4237 稻草人 題解
我們考慮分治一下 按 x 座標排序 然後對於每一段的兩部分都按 y 排序 左右兩邊都維護乙個單調棧 然後考慮右邊對左邊的貢獻就行了 include define int long long using namespace std const int maxn 2e5 5 int n struct n...