ACM-ICPC 2018 徐州賽區網路預賽 G. Trace (線段樹維護)
阿新 • • 發佈:2018-11-04
題意
你在海灘上有浪花,所有的浪花都是矩形的,當一個浪花來了之後,就會覆蓋他的前一個浪花,問你最後浪花的周長和
思路
我們從後往前來,這樣的話,我們處理的都是會留下來的,怎樣的會留下來呢?
首先我們先看1號點和2號點,由圖我們可以很明顯的看出1號點會被淹沒,而1`和1“他們不會被淹沒,所以對於我們當前的值來說,我們維護一下大於他的x的最大的y,和大於他的y座標的最大的x,這兩個值,然後每次查詢之後觀察我們當前的x[i],和y[i]的關係,加上貢獻就好,具體怎麼維護,我們把所有點離散下來,建兩顆線段樹,1顆以x的座標為線段樹的區間,y為線段樹的權值維護y的最大值,x座標反之,之後對於查詢*(x,y),我們查 (x,n)區間中的最大值,二維變一維了就。
程式碼
#include<bits/stdc++.h>
#define rep(i,j,k) for(int i=j;i<=k;i++)
#define rrep(i,j,k) for(int i=j;i>=k;i--)
#define println(a) printf("%lld\n",(ll)(a))
#define printbk(a) printf("%lld ",(ll)(a))
typedef long long ll;
using namespace std;
const int MAXN = 2e5+11;
const ll oo = 0x3f3f3f3f3f3f3f3f ;
const ll ooo= 0x3f3f3f3f;
const int MOD = 1e9+7;
ll read(){
ll x=0,f=1;register char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
struct ST{
#define lc o<<1
#define rc o<<1|1
ll mx[MAXN<<2];
void pu(int o){
mx[o]=max(mx[lc],mx[rc]);
}
void update(int o,int l,int r,int k,ll v){
if(l==r){
mx[o]=max(mx[o],v);
return;
}
int mid=l+r>>1;
if(k<=mid) update(lc,l,mid,k,v);
else update(rc,mid+1,r,k,v);
pu(o);
}
ll query(int o,int l,int r,int L,int R){
if(L<=l&&r<=R) return mx[o];
int mid=l+r>>1;
ll ans=0;
if(L<=mid) ans=max(ans,query(lc,l,mid,L,R));
if(R>mid) ans=max(ans,query(rc,mid+1,r,L,R));
return ans;
}
}st[2];
struct QAQ{
int x, y;
int _x,_y;
QAQ(int Q=0,int A=0){
x=Q;
y=A;
}
}a[MAXN];
int xx[MAXN],yy[MAXN],n;
int main(){
while(cin>>n){
int cnt=0;
rep(i,1,n){
int x=read();
int y=read();
a[i]=QAQ(x,y);
xx[++cnt]=x;
yy[cnt]=y;
}
sort(xx+1,xx+1+cnt);
sort(yy+1,yy+1+cnt);
rep(i,1,n){
a[i]._x=lower_bound(xx+1,xx+1+cnt,a[i].x)-xx;
a[i]._y=lower_bound(yy+1,yy+1+cnt,a[i].y)-yy;
}
// for(int i = 1 ; i <= n ; i++) printf("%d %d\n",a[i]._x,a[i]._y);
rep(i,0,1) memset(st[i].mx,0,sizeof st[i].mx);
//st[0]: x座標下最大的y
//st[1]: y座標下最大的x
ll ans=0;
rrep(i,n,1){
int x=a[i].x;
int y=a[i].y;
int xid=a[i]._x;
int yid=a[i]._y;
ll t1=st[1].query(1,1,cnt,yid,cnt);
if(t1<x) ans+=x-t1;
st[1].update(1,1,cnt,yid,x);
ll t2=st[0].query(1,1,cnt,xid,cnt);
if(t2<y) ans+=y-t2;
st[0].update(1,1,cnt,xid,y);
}
println(ans);
}
return 0;
}