全球覆蓋 雜湊
阿新 • • 發佈:2020-09-08
# 全球覆蓋 雜湊
## 題目描述
小黑正在研發一款全球定位軟體,想用它來定位小白的座標。
具體來說,地球可以看做一個$X \times Y$的網格矩陣,橫縱座標範圍分別是$[0, X)$和$[0, Y)$,由於地球是球形結構,網格的上邊界和下邊界是相通的,左邊界和右邊界也是相通的。
現在小黑獲得了$n$組座標對,每組座標對含有兩個點的座標$(x_i,0 , y_i,0 ), (x_i,1 , y_i,1 )$,表示地球上一個兩邊平行於座標軸的矩形的兩個對角頂點,而小白就在這個矩形內部。
然而,由於地球是球形結構,確定了座標對後仍然有多種可能的“矩形”(如下
圖所示)。小黑想知道最多可能有多少面積的網格出現在所有“矩形”的交集之中,
以方便他確定小白的位置。每個單元格的面積為$1$。
於是他把這個問題交給你了。
![](https://img2020.cnblogs.com/blog/1996139/202009/1996139-20200908200657958-189770529.png)
## 輸入格式
從檔案 $globe.in$ 中讀入資料。
第一行三個正整數$n, X, Y$,含義如題目描述。
接下來n行,每行四個正整數$x_i,0 , y_i,0 , x_i,1 , y_i,1$ ,描述一組座標對。所有資料始終保
證有$x_i,0 < x_i,1 , y_i,0 < y_i,1$ 。
## 輸出格式
輸出到檔案 $globe.out$ 中。
一行,一個整數,表示所求的答案。
### 樣例 1 輸入
> 2 10 7
2 1 8 6
4 2 5 4
### 樣例 1 輸出
> 15
### 樣例 1 解釋
樣例中的情況和題目中圖片一致,其中第三種情況的面積最大。
### 樣例 2
見下發檔案中的$globe2.in$和$globe2.ans$。
## 資料範圍
對於前$10\%$ 的資料,$n ≤ 10$。
對於前$20\%$ 的資料,$n ≤ 20$。
對於另$50\%$ 的資料,$n ≤ 3000$。
對於$100\%$ 的資料,$n ≤ 500000,2 ≤ X, Y ≤ 10 9 , 0 ≤ x_0 , x_1 < X, 0 ≤ y_0 , y_1 < Y$。
## 分析
我們可以發現橫縱座標互不相關,因此可以對於橫縱座標分別列舉求出最大值,再相乘即可
現在考慮怎麼單獨求出橫座標或者縱座標的最大值
顯然,我們所選擇的線段一定是被兩組相鄰的線段所截得的
而且如果我們要把多個線段拼到一起的話,這些線段必須滿足截得它們的線段的價值相同
![](https://img2020.cnblogs.com/blog/1996139/202009/1996139-20200908203323532-369285777.png)
比如說上面這一幅圖,如果我們去找能與$1$號線段合併的線段,那麼我們就去看其它四條線段兩端的顏色是否$1$好線段的顏色相同,我們發現$5$號線段滿足這個條件,那麼我們就把$1$號線段和$5$號線段合併
同理,我們還可以把$2$號線段和$4$號線段合併,而$3$號線段沒有可以與它合併的
那麼暴力的思路就是用$n^2$的效率去列舉兩條線段看它們是否能合併在一起
實際上,我們可以對與每條線段取一個貢獻的雜湊值,將這些雜湊值存在雜湊表裡,每次加入線段時遇到雜湊值相同的就合併
合併時取一個最大值即可
## 程式碼
``` cpp
#include
#include
#include
#include
inline int read(){
int x=0,fh=1;
char ch=getchar();
while(ch<'0' || ch>'9'){
if(ch=='-') fh=-1;
ch=getchar();
}
while(ch>='0' && ch<='9'){
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x*fh;
}
const int maxn=2e6+5;
typedef unsigned long long ll;
const ll bas=131;
int ans=0;
struct m_hash{
static const ll Mod=261807;
struct asd{
int next,jz;
ll val;
}b[maxn];
int head[maxn],tot;
m_hash(){
memset(head,-1,sizeof(head));
tot=1;
}
void ad(int cd,ll val){
int now=val%Mod;
for(int i=head[now];i!=-1;i=b[i].next){
ll u=b[i].val;
if(u==val){
b[i].jz+=cd;
ans=std::max(ans,b[i].jz);
return;
}
}
b[tot].val=val;
b[tot].jz=cd;
ans=std::max(ans,b[tot].jz);
b[tot].next=head[now];
head[now]=tot++;
}
}mp1,mp2;
struct asd{
int val,id,jud;
asd(){}
asd(int aa,int bb,int cc){
val=aa,id=bb,jud=cc;
}
}a[maxn],b[maxn];
bool cmp(asd aa,asd bb){
return aa.val