Problem:
Score : 500 points

Problem Statement

There are N points on the 2D plane, i-th of which is located on (x_i, y_i).
There can be multiple points that share the same coordinate.
What is the maximum possible Manhattan distance between two distinct points?

Here, the Manhattan distance between two points (x_i, y_i) and (x_j, y_j) is defined by |x_i-x_j| + |y_i-y_j|.

Constraints

2 \leq N \leq 2 \times 10^5

1 \leq x_i,y_i \leq 10^9

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
x_1 y_1
x_2 y_2
:
x_N y_N

Output

Print the answer.

Sample Input 1

3
1 1
2 4
3 2

Sample Output 1

4

The Manhattan distance between the first point and the second point is |1-2|+|1-4|=4, which is maximum possible.

Sample Input 2

2
1 1
1 1

Sample Output 2

0

Solution in C++ (GCC 9.2.1) (judge verdict: Runtime Error)

#include <bits/stdc++.h>
#define int long long
using namespace std;

int n,q,pos=0,ans=0;
int tag[2000005],v1[100005],v2[100005];

map<int,int> m;

struct node
{
	int l,r;
}b[100005];

struct node2
{
	int rt;
	int num;
}cf[100005];

struct segment_tree
{
	int maxv,minv;
}tree[2000005];

inline void pushup(int rt)
{
	tree[rt].maxv=max(tree[2*rt].maxv,tree[2*rt+1].maxv);
	tree[rt].minv=min(tree[2*rt].minv,tree[2*rt+1].minv);
}

inline void change_max(int nl,int l,int r,int rt,int k)
{
	if (l==r&&l==nl)
	{
		tree[rt].maxv=max(tree[rt].maxv,k);
		return;
	}
	int mid=(l+r)>>1;
	if (nl<=mid)  change_max(nl,l,mid,2*rt,k);
	else change_max(nl,mid+1,r,2*rt+1,k);
	
	pushup(rt);
}

inline void change_min(int nl,int l,int r,int rt,int k)
{
	if (l==r&&l==nl)
	{
		tree[rt].minv=min(tree[rt].minv,k);
		return;
	}
	int mid=(l+r)>>1;
	if (nl<=mid)  change_min(nl,l,mid,2*rt,k);
	else change_min(nl,mid+1,r,2*rt+1,k);
	
	pushup(rt);
}

int query_max(int nl,int nr,int l,int r,int rt)
{
	int sumv=0,mid=(l+r)>>1;
	
	if (nl<=l&&r<=nr)  return tree[rt].maxv;
	if (nl<=mid)  sumv=max(sumv,query_max(nl,nr,l,mid,2*rt));
	if (nr>mid)  sumv=max(sumv,query_max(nl,nr,mid+1,r,2*rt+1));
	return sumv;
}

int query_min(int nl,int nr,int l,int r,int rt)
{
	int sumv=1e18+7,mid=(l+r)>>1;
	
	if (nl<=l&&r<=nr)  return tree[rt].minv;
	if (nl<=mid)  sumv=min(sumv,query_min(nl,nr,l,mid,2*rt));
	if (nr>mid)  sumv=min(sumv,query_min(nl,nr,mid+1,r,2*rt+1));
	return sumv;
}

bool cmp(node2 x,node2 y)
{
	return x.num<y.num;
}

bool cmp2(node x,node y)
{
	return x.l<y.l;
}

inline void clear()
{
	for (int i=1;i<=8*n;i++)  tree[i].maxv=tag[i]=0,tree[i].minv=1e18+7;
}

signed main()
{
	cin>>n;
	for (int i=1;i<=n;i++)
	{
		cin>>b[i].l>>b[i].r;
	}
	sort(b+1,b+n+1,cmp2);
	for (int i=1;i<=n;i++)
	{
		v1[i]=b[i].l+b[i].r;
	  	v2[i]=b[i].r-b[i].l;
	}
	for (int i=1;i<=n;i++)
	{
		cf[++pos].num=b[i].l,cf[pos].rt=pos;
		cf[++pos].num=b[i].r,cf[pos].rt=pos;
	}
	sort(cf+1,cf+2*n+1,cmp);
	
	int now=0;
	for (int i=1;i<=2*n;i++)
	{
		if (cf[i].num!=cf[i-1].num)  now++,m[cf[i].num]=now;
	}
	for (int i=1;i<=n;i++)  b[i].l=m[b[i].l],b[i].r=m[b[i].r];
	
	clear();
	for (int i=1;i<=n;i++)
	{
		if (i!=1)  ans=max(ans,v1[i]-query_min(1,b[i].r,1,2*n,1));
		change_min(b[i].r,1,2*n,1,v1[i]);
	}
	clear();
	for (int i=1;i<=n;i++)
	{
		if (i!=1)  ans=max(ans,query_max(b[i].r+1,2*n,1,2*n,1)-v2[i]);
		change_max(b[i].r,1,2*n,1,v2[i]);
	}
	cout<<ans<<endl;
	
	return 0;
}