记录编号 234117 评测结果 AAAAAAAAAA
题目名称 [SPOJ 1960] 矩形 最终得分 100
用户昵称 Gravatarmikumikumi 是否通过 通过
代码语言 C++ 运行时间 2.978 s
提交时间 2016-03-06 21:31:14 内存使用 977.42 MiB
显示代码纯文本
#include<cstdio>
#include<deque>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<map>
using namespace std;
const int SIZEN=250010;
typedef long long LL;
int totx=0,toty=0;
deque<int> posy[SIZEN];
int posx[SIZEN];
int X[SIZEN],Y[SIZEN];
int N;
LL ans=0;
class miku
{
public:
	int x,y;
}P[SIZEN];
int get() {
  int ans=0;
  char tmp=getchar();
  int now=1;
  while((tmp<'0'||tmp>'9')&&tmp!='-') tmp=getchar();
  if(tmp=='-') now=-1,tmp=getchar();
  while(tmp>='0'&&tmp<='9'){
      ans=ans*10+tmp-'0';
      tmp=getchar(); 
  }
  ans*=now;
  return ans;
}
void read()
{
	scanf("%d",&N);
	for(int i=1;i<=N;i++) 
	{
		scanf("%d%d",&P[i].x,&P[i].y);
		X[++totx]=P[i].x;
		Y[++toty]=P[i].y;
	}
}
void prepare()
{
	sort(X+1,X+totx+1);
	totx=unique(X+1,X+totx+1)-X-1;
	for(int i=1;i<=N;i++) P[i].x=lower_bound(X+1,X+totx+1,P[i].x)-X;
	sort(Y+1,Y+toty+1);
	toty=unique(Y+1,Y+toty+1)-Y-1;
	for(int i=1;i<=N;i++) P[i].y=lower_bound(Y+1,Y+toty+1,P[i].y)-Y;
}
int best;
deque<int> Q1;//这是要用算法一处理的行
deque<int> Q2;//这是要用算法二处理的行
bool sp[SIZEN]={0};//当前这一行是否处理过
void planA()
{
	bool H[SIZEN];
	for(int i=0;i<Q1.size();i++)
	{
		int x=Q1[i];
		sp[x]=1;
		//cout<<x<<endl;
		for(int j=0;j<posy[x].size();j++) 
		{
			int y=P[posy[x][j]].x;
			H[y]=1;
			//cout<<y<<" ";
		}
		//cout<<endl;
		for(int j=1;j<=toty;j++)
		{
			LL now=0;
			if(sp[j]) continue;
			for(int k=0;k<posy[j].size();k++) 
			{
				int y=P[posy[j][k]].x;
				if(H[y]) now++;
			}
			ans+=now*(now-1);
			//cout<<j<<" "<<now<<endl;
		}
		for(int j=0;j<posy[x].size();j++) 
		{
			int y=P[posy[x][j]].x;
			H[y]=0;
		}
	}
}
miku line[SIZEN*500];
bool cmp(miku a,miku b)
{
	if(a.x==b.x) return a.y<b.y;
	return a.x<b.x;
}
void planB()
{
	int tot=0;
	for(int k=0;k<Q2.size();k++)
	{
		int x=Q2[k];
		for(int i=0;i<posy[x].size();i++)
		{
			for(int j=i+1;j<posy[x].size();j++)
			{
				int temx=P[posy[x][i]].x,temy=P[posy[x][j]].x;
				line[++tot].x=temx,line[tot].y=temy;
				if(line[tot].x>line[tot].y) swap(line[tot].x,line[tot].y);
			}
		}
	}
	sort(line+1,line+1+tot,cmp);
	//for(int i=1;i<=tot;i++) cout<<line[i].x<<" "<<line[i].y<<endl;
	int i=1,j;
	while(i<tot)
	{
		j=i+1;
		while(j<=tot&&line[i].x==line[j].x&&line[i].y==line[j].y) j++;
		LL now=j-i;
		ans+=now*(now-1);
		i=j;
	}
}
void work()
{
	for(int i=1;i<=N;i++) posy[P[i].y].push_back(i);
	best=sqrt(N+1.0);
	for(int i=1;i<=toty;i++) 
		if(posy[i].size()>best) Q1.push_back(i);
	else Q2.push_back(i);
	//cout<<Q1.size()<<" "<<Q2.size()<<endl;
	planA();
	planB();
	ans/=2;
	printf("%lld",ans);
}
int main()
{
	freopen("RECTANGL.in","r",stdin);
	freopen("RECTANGL.out","w",stdout);
	read();
	prepare();
	//for(int i=1;i<=N;i++) cout<<P[i].x<<" "<<P[i].y<<endl;
	work();
	return 0;
}