题目链接:https://nanti.jisuanke.com/t/31459
#include<bits/stdc++.h>
#pragma comment(linker,"/STACK:1024000000,1024000000")
using namespace std;#define debug puts("YES");
#define rep(x,y,z) for(int (x)=(y);(x)<(z);(x)++)
#define read(x,y) scanf("%d%d",&x,&y)#define lrt int l,int r,int rt
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define ll long long
const int maxn =1e6+5;
const int mod=1e9+7;
ll powmod(ll x,ll y) {ll t;for(t=1;y;y>>=1,x=x*x%mod) if(y&1) t=t*x%mod;return t;}
ll gcd(ll x,ll y) { return y==0?x:gcd(y,x%y); }set<int> sx,sy;///维护横纵轴坐标
set<int>:: iterator it;
int x[maxn],y[maxn],n;///集合
/*
题目大意:几何矩形覆盖问题,
跟时间序列有关的覆盖。技巧思维题:
这类题目有些特征,
就是前面的答案可能会受到后面答案的影响,
所以要倒叙思考。
据题目,最后一个插入的矩形肯定是
全部保留下来的。
不妨维护一个x轴和y轴集合,
然后每次插入的x,y线段,
可以看成是一系列有时间顺序的长度序列,
时间倒过来后,新加的序列线段一定是亏损过的,
手动模拟后,不难发现
(注意题目中要求没有两个完全覆盖的关系的矩形,这很关键~)
新加的矩形一定至少要相交一条边,并且是在阶梯的拐角上加边,
即每次肯定都是形成新的阶梯状,
这样对于每次加入的边,
模拟中只要找到最后一个比其小的边做差,答案贡献个差值即可。*/int main()
{scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d%d",&x[i],&y[i]);sx.clear();sy.clear();ll ans=0;for(int i=n-1;i>=0;i--){it=sx.lower_bound(x[i]);if(it==sx.begin() || sx.empty() ) ans+=x[i];else ans+=(x[i]-*(--it));it=sy.lower_bound(y[i]);if(it==sy.begin() || sy.empty() ) ans+=y[i];else ans+=(y[i]-*(--it));sx.insert(x[i]);sy.insert(y[i]);}printf("%lld\n",ans);return 0;
}