前言
网上代码各种各样的都可以AC,但关于判断横(纵)坐标相同是否构成矩形这一点各有不同。实际上,题目数据没有横坐标标或者纵坐标相同的情况,所以放心AC。
sol
CDQ分治都看得出来。反正按纵坐标分为上下两层,然后考虑上对下的贡献。由于不能跨点,研究一个性质放在单调队列里就行了。
比普通分治还是多一个思维.提高组T1难度吧
code
#include<bits/stdc++.h>
#define LL long long
using namespace std;
int N;
template <class T>
inline void read(T&data){
register char ch=0;data=0;
while(ch<'0'||ch>'9')ch=getchar();
while(ch<='9'&&ch>='0'){
data=(data<<3)+(data<<1)+(ch^48);
ch=getchar();
}
}
const int _ = 2e5+1021;
struct poi{
int x,y;
}p[_],zjy[_];
LL ans=0;int n;
int QL[_],QR[_];
LL tree[_];
bool cmp(register poi a,register poi b){
return a.y<b.y;
}
bool cmp2(register poi a,register poi b){
return a.x<b.x;
}
inline int lowbit(register int k){return k&(-k);}
inline void modify(register int loc,register int zh){
for(register int i=loc;i<=n;i+=lowbit(i))tree[i]+=zh;
}
inline LL query(register int loc1,register int loc2){
/*--loc1;*/loc1=max(0,loc1);
register LL ret1=0,ret2=0;
for(register int i=loc1;i;i-=lowbit(i))ret1+=tree[i];
for(register int i=loc2;i;i-=lowbit(i))ret2+=tree[i];
return ret2-ret1;
}
void CDQ(register int L,register int R){
if(L==R)return;
register int mid = (L+R)>>1;
CDQ(L,mid),CDQ(mid+1,R);
register int pin1=L,pin2=mid+1,ppl=L,lc=0,rc=0;
for(;pin2<=R;++pin2){
while(rc&&p[QR [ rc ] ].y >= p[pin2 ].y)--rc;
QR[++rc]=pin2;
while(p[pin1].x<=p[pin2].x&&pin1<=mid){
while(p[pin1].y>p[QL[lc]].y&&lc>0){
modify(p[QL[lc]].x,-1);--lc;
}
QL[++lc]=pin1;modify(p[pin1].x,1);
zjy[ppl]=p[pin1];
++pin1;++ppl;
}
zjy[ppl]=p[pin2];++ppl;
ans+=query(p[QR[rc-1]].x,p[QR[rc]].x);
}
while(lc)
modify(p[QL[lc]].x,-1),--lc;
while(pin1<=mid){
zjy[ppl]=p[pin1],++pin1,++ppl;
}
for(register int i=L;i<=R;++i)p[i]=zjy[i];
}
int main(){
read(n);
for(register int i=1;i<=n;++i){
read(p[i].x),read(p[i].y);
}
sort(p+1,p+n+1,cmp);//横、纵坐标太大了
for(register int i=1,pre=-1,sum=0;i<=n;++i){
if(p[i].y==pre)p[i].y=sum;
else
pre=p[i].y,p[i].y=++sum;
}
sort(p+1,p+n+1,cmp2);
for(register int i=1,pre=-1,sum=0;i<=n;++i){
if(p[i].x==pre)p[i].x=sum;
else pre=p[i].x,p[i].x=++sum;
}
sort(p+1,p+n+1,cmp);
CDQ(1,n);
printf("%lld\n",ans);
}