1. 程式人生 > >全球覆蓋 雜湊

全球覆蓋 雜湊

# 全球覆蓋 雜湊 ## 題目描述 小黑正在研發一款全球定位軟體,想用它來定位小白的座標。 具體來說,地球可以看做一個$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