题面:
赛时给我搞破防了,没有一点思路。
Part1
对于这四种神奇有病的操作,可以把 \(x\)轴 和 \(y\)轴 分开考虑,它们之间互不影响。最后答案就是 \(x\)轴上的最长距离 乘 \(y\)轴上的最长距离。这样就把二维的问题拆分成了两个序列上的问题。现在问题变成了给定几个区间,可以取区间的中间或者两边,求所有区间交集的最大长度。
Part2
把每个区间的端点离散成若干个点,我们发现对于两个点之间的线段,要想要使其成为答案的一部分,每个区间的状态是确定的,这里状态指取中间或者取两边,不存在两种状态都可以的情况。我们把每个区间的状态成为需求。
只要满足需求,这个线段就可以被算进答案里,那我们把需求 哈希 一下, 给每个哈希值累加长度, 最后给每个需求取个 \(\max\) 就可以了
复杂度 \(\Theta(n)\)
Code
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <unordered_map>
#define ull unsigned long long
#define int long long
const int N=5e5+10;
const int base=233;
using namespace std;
inline int read() {
int f=1, x=0;
char ch=getchar();
while(ch>'9' || ch<'0') {
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0' && ch<='9') {
x=(x<<3)+(x<<1)+(ch^48);
ch=getchar();
}
return f*x;
}
inline void write(int x) {
cout<<x; putchar('\n');
}
int n, X, Y, ans=1, lim, tot, cnt;
struct Martix {
int x1, y1;
int x2, y2;
}mart[N];
struct Point {
int pos, bel;
}p[N<<1];
ull power[N];
unordered_map <ull, int> mp;
void prework() {
power[0]=1;
for(int i=1;i<=N-5;i++) {
power[i]=power[i-1]*base;
}
}
bool cmp(Point a,Point b) {
return a.pos < b.pos;
}
void init(int x) {
tot=0, lim=x;
cnt=0, mp.clear();
}
int work() {
sort(p+1, p+tot+1, cmp);
int res=0;
p[++tot].pos=lim;
ull ha=0;
mp[0]=p[1].pos;
for(int i=1;i<tot;i++) {
int l=p[i].pos, r=p[i+1].pos;
ha^=power[p[i].bel];
mp[ha]+=r-l;
res=max(res,mp[ha]);
}
return res;
}
signed main() {
n=read(), X=read() ,Y=read();
prework();
for(int i=1;i<=n;++i) {
mart[i]=(Martix){read(), read(), read(), read()};
}
init(X);
for(int i=1;i<=n;i++) {
p[++tot].pos=mart[i].x1;
p[tot].bel=i;
p[++tot].pos=mart[i].x2;
p[tot].bel=i;
}
ans*=work();
init(Y);
for(int i=1;i<=n;i++) {
p[++tot].pos=mart[i].y1;
p[tot].bel=i;
p[++tot].pos=mart[i].y2;
p[tot].bel=i;
}
ans*=work();
write(ans);
return 0;
}