题目大意:
给出那个点
求这样的点对个数:以两点连线为对角线的矩形内不存在其他点(也不能在边界上)
首先注意到:对于某一个点p,我们考虑y值大于等于p的其他点
那么可行的点若在p的左边,y值一定单调递增,在右边则单调递减
我们只考虑左边的(右边的可以通过坐标变换变到左边来)
那么用树状数组套单调队列,可以维护一段单调的y值,
另外就是单调队列的合并问题:
树状数组不断往回跳的时候,会碰到两个单调队列的合并,这个比较好做……不详细写了……
然后还有算重的问题,在一开始减掉就行了
第一次写数据结构套数据结构的题……
pty的做法是开了一个大数组,我由于有把数据结构写成类的“良好习惯”
所以不太好这么做,于是我把树状数组的每个节点开成了个deque……
导致的结果是pty234ms,我1.4s+……常数巨大……本来写这种做法而不是分治就是为了节省常数的说……
嗯……详见代码好了……自认为写的比较好看……
PS:我wa6wa了很久,原因是因为我减去算重的部分的时候0那个位置没有开哨兵……就是没有赋成无穷……我自己怎么拍也拍不出来……sgu数据太强了……
另外,由于我在struct里开了10w个deque,3.x的g++貌似编译不过……反正我dev c++各种蛋疼……
code:
//Lib
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#include<queue>
#include<stack>
#include<set>
#include<map>
using namespace std;
//Macro
#define rep(i,a,b) for(int i=a,tt=b;i<=tt;++i)
#define drep(i,a,b) for(int i=a,tt=b;i>=tt;--i)
#define erep(i,e,x) for(int i=x;i;i=e[i].next)
#define irep(i,x) for(__typeof(x.begin()) i=x.begin();i!=x.end();i++)
#define read() (strtol(ipos,&ipos,10))
#define sqr(x) ((x)*(x))
#define pb push_back
#define PS system("pause");
typedef long long ll;
typedef pair<int,int> pii;
const int oo=~0U>>1;
const double inf=1e100;
const double eps=1e-6;
string name="love", in=".in", out=".out";
//Var
int n,cnt;
long long ans;
int lisan[100008];
struct P
{
int x,y;
bool operator <(const P &o)const{return y>o.y||y==o.y&&x<o.x;};
bool operator ==(const P &o)const{return x==o.x&&y==o.y;}
}p[100008];
struct MQ
{
deque<pii> q;
void Insert(int x,int y)
{
while(!q.empty()&&q.front().second<=x)q.pop_front();
q.push_front(pii(y,x));
}
int Union(int x)
{
return lower_bound(q.begin(),q.end(),pii(x,0))-q.begin()-1;
}
};
struct TA
{
MQ q[100008];
void set(){rep(i,1,cnt)q[i].q.clear();}
inline int lowbit(int x){return x&-x;}
int Query(int x)
{
int ret=0,pos,now=oo;
for(int i=x;i>0;i-=lowbit(i))
{
if(q[i].q.empty())continue;
pos=q[i].Union(now);
if(pos==-1)continue;
ret+=pos+1;
now=q[i].q[0].first;
}
return ret;
}
void Insert(int x,int y)
{
for(int i=x;i<=cnt;i+=lowbit(i))
q[i].Insert(x,y);
}
}T;
void Init()
{
scanf("%d",&n);
set<int> s;
rep(i,1,n)
{
scanf("%d%d",&p[i].x,&p[i].y);
if(!s.insert(p[i].x).second)ans--;
}
sort(p+1,p+1+n);p[0].y=-oo;
rep(i,1,n)if(p[i].y==p[i-1].y)ans--;
irep(i,s)lisan[++cnt]=*i;
rep(i,1,n)p[i].x=lower_bound(lisan+1,lisan+1+cnt,p[i].x)-lisan;
}
int Calc(P &x)
{
int ret=T.Query(x.x);
T.Insert(x.x,x.y);
return ret;
}
void Work()
{
rep(i,1,n)ans+=Calc(p[i]);
rep(i,1,n)p[i].x=cnt-p[i].x+1;
sort(p+1,p+1+n);
T.set();
rep(i,1,n)ans+=Calc(p[i]);
cout<<ans<<endl;
}
int main()
{
// freopen((name+in).c_str(),"r",stdin);
// freopen((name+out).c_str(),"w",stdout);
Init();
Work();
// PS;
return 0;
}