【ACM-ICPC 2018 徐州賽區網路預賽 G. Trace】 離散化+權值線段樹
阿新 • • 發佈:2018-12-10
題目連結 https://nanti.jisuanke.com/t/31459 題意 *做法 程式碼
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define dbg(x) cout<<#x<<" = "<<x<<endl
const int maxn = 1e5+10;
int x[maxn],y[maxn];
int Hash_x[maxn],Hash_y[maxn];
int getid(int a[],int n,int x)
{
return lower_bound(a+1,a+1+n,x)-a;
}
struct T
{
int l,r,mid,val;
int add;
}tree_x[maxn<<2],tree_y[maxn<<2];
void push_up(T tree[],int rt)
{
tree[rt].val=max(tree[rt<<1].val,tree[rt<<1|1].val);
}
void push_down(T tree[],int rt)
{
if(tree[rt].add)
{
tree[rt<<1].add=max(tree[rt<<1].add,tree[rt].add);
tree[rt<<1].val=max(tree[rt<<1].val,tree[rt].add);
tree[rt<<1|1].add=max(tree[rt<<1|1].add,tree[rt].add);
tree[rt<<1|1].val=max(tree[rt<<1|1].val,tree[rt].add);
tree[rt].add=0;
}
}
void build(T tree[],int rt,int l,int r)
{
tree[rt].l=l;
tree[rt].r=r;
tree[rt].add=0;
if(l==r) return ;
int mid=tree[rt].mid=l+r>>1;
build(tree,rt<<1,l,mid);
build(tree,rt<<1|1,mid+1,r);
push_up(tree,rt);
}
void update(T tree[],int rt,int l,int r,int val)
{
if(r<tree[rt].l||l>tree[rt].r) return ;
if(l<=tree[rt].l&&tree[rt].r<=r)
{
tree[rt].add=max(tree[rt].add,val);
tree[rt].val=max(tree[rt].val,val);
return ;
}
push_down(tree,rt);
if(l<=tree[rt].mid) update(tree,rt<<1,l,r,val);
if(r>tree[rt].mid) update(tree,rt<<1|1,l,r,val);
push_up(tree,rt);
}
int query(T tree[],int rt,int pos)
{
if(tree[rt].l==tree[rt].r) return tree[rt].val;
push_down(tree,rt);
long long ans;
if(pos<=tree[rt].mid) ans=query(tree,rt<<1,pos);
else ans=query(tree,rt<<1|1,pos);
push_up(tree,rt);
return ans;
}
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d%d",&x[i],&y[i]);
for(int i=1;i<=n;i++)
{
Hash_x[i]=x[i];
Hash_y[i]=y[i];
}
sort(Hash_x+1,Hash_x+1+n);
sort(Hash_y+1,Hash_y+1+n);
int d_x=unique(Hash_x+1,Hash_x+1+n)-Hash_x-1;
int d_y=unique(Hash_y+1,Hash_y+1+n)-Hash_y-1;
build(tree_x,1,1,d_x);
build(tree_y,1,1,d_y);
long long ans=0;
for(int i=n;i>=1;i--)
{
int posx=getid(Hash_x,d_x,x[i]);
int posy=getid(Hash_y,d_y,y[i]);
int tmp=query(tree_x,1,posx);
if(tmp<y[i]) ans+=y[i]-tmp;
tmp=query(tree_y,1,posy);
if(tmp<x[i]) ans+=x[i]-tmp;
update(tree_x,1,1,posx,y[i]);
update(tree_y,1,1,posy,x[i]);
}
printf("%lld\n",ans);
return 0;
}