【noi.ac #1773】. function

題目

Description
平面上有 n 個不同的點。

一共有 Q 次詢問,每次指出一個左下角在 (x1,y1)、右上角在 (x2,y2) 的矩形(注意可能退化成線段或者點),考慮這個矩形內部或者邊界上的所有點,詢問一共有多少不同的 x 座標以及多少不同的 y 座標。

注意每次詢問給出的 (x1,y1,x2,y2) 並不是矩形的真實參數。假設上一個詢問的兩個答案分別是 ansx 和 ansy (初始時 ansx=ansy=0),則真正的矩形參數由以下公式計算得到(⊕ 表示二進制按位異或):x

1
=x1⊕(ansx×T),x

2
=x2⊕(ansx×T),y

1
=y1⊕(ansy×T),y

2
=y2⊕(ansy×T)。其中 T∈{0,1}
Input
第一行讀入一個整數 n (1≤n≤5×104)。 接下來 n 行每行兩個整數 (x,y) (0≤x,y,≤5×105),表示點的座標。 接下來一行讀入兩個整數 Q,T (1≤q≤5×104,T∈{0,1})。 接下來 n 行每行四個整數 x1,y1,x2,y2,表示計算前矩形的四個參數。保證計算後的參數滿足 0≤x

1
≤x

2
≤5×105,0≤y

1
≤y

2
≤5×105
Output
對於每個詢問輸出兩個整數 ansx,ansy,分別表示不同的 x 座標數量和不同的 y 座標數量。

Sample Input1
4
2 0
2 1
1 1
1 2
4 0
0 0 2 2
1 1 2 2
1 0 2 1
0 0 1 1
Sample Output1
2 3
2 2
2 2
1 1
Sample Input2
10
8 1
9 10
9 1
0 1
0 1
5 10
0 1
5 1
5 10
5 1
5 1
2 0 8 8
4 0 8 7
7 5 8 11
2 3 3 9
0 5 7 10
Sample Output2
2 1
2 1
2 1
0 0
1 1
Hint
一共有 10 組測試數據。

測試點編號 特殊性質
1,2 1≤n,Q≤1000
3,4 對於讀入的 n 個點,不同的 x 座標數量和不同的 y 座標數量均 ≤100
5,6 每個點的 x 座標和解碼後的 x1,x2 均相等
4,5,8 1≤n,Q≤30000
1,3,5,7,9 T=0
2,4,6,8,10 T=1

思路

從經典的樹套樹角度出發。我們把 xx 作爲線段樹的下標,這樣矩陣的 [x1,x2][x_1,x_2] 限制可以劃成 O(logn)O(\log n) 個獨立的詢問,對於每個詢問我們只需考慮 [y1,y2][y_1,y_2] 的限制就好了。依次考慮這個節點包含的每個橫座標 ,怎樣才能對當前詢問產生貢獻呢?假設這個座標下一共有 kk 個點,它們對應的有序縱座標爲 y1,y2,,yky_1,y_2,\cdots,y_k,我們可以抽象出 kk 個不相交矩陣 [0,y1,y1,+],[y1+1,y2,y2,+],[yk1,yk,yk,+],[0,y_1,y_1,+\infty],[y_1+1,y_2,y_2,+\infty],[y_{k-1},y_k,y_k,+\infty],——如果詢問 [y1,y2][y_1,y_2] 落在某個矩陣內部就可以產生 11 的貢獻。自此我們將問題轉化成了 線段樹套二維數點。可以套傳統二維數點或者KDTREE,期望效率是 O(Qlog3n)O(Q \log^3 n)O(Qlognn)O(Q \log n \sqrt n),可能會超時。

介紹一個比較取巧的做法——當 nn 規模在 5×1045 \times 10^4 的時候可以考慮 bitset。 對離散後的 xx 座標分塊。我們可以預先開 O(n)O(n) 個 , fi,jf_{i,j} 記錄塊 ii 到塊 jj 之間的答案,預處理複雜度 O(nn+n2w)O(n \sqrt n + \frac{n^2}{w})。詢問時直接得到塊間的答案,枚舉左右兩個零散的部分加入 。
期望效率 O((Q+n)n+(Q+n)nw)O((Q+n) \sqrt n + \frac{(Q+n)n}{w}),常數也很小。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章