Cod sursa(job #220492)

Utilizator gigi_becaliGigi Becali gigi_becali Data 11 noiembrie 2008 02:13:56
Problema Cutii Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 5.58 kb
using namespace std;
#include <algorithm>
#include <cstdio>
#include <string>
#include <ctime>
#define DIM 8192
#define N 100001
#include <cmath>
#define maxh 666013
char ax[DIM+16];
int pz;

struct nd{ int x, y;bool r;nd*n;};
nd *H[maxh];
inline void insert(int x, int y,bool r)
{
    int h=(((x+100001)*23)%maxh+(y+100001))%maxh;

    nd *p=new nd;
    p->x=x;
    p->y=y;
    p->r=r;
    p->n=H[h];
    H[h]=p;

}

inline int find(int x, int y)
{
    int h=(((x+100001)*23)%maxh+(y+100001))%maxh;

    for(nd *p=H[h]; p; p=p->n)
	if(p->x == x && p->y == y) return p->r;
    return -1;
}
inline void cit(int &x)
{
            x=0;
            while((ax[pz]<'0' || ax[pz]>'9') && (ax[pz]!='-'))
                        if(++pz==DIM)fread(ax, 1, DIM, stdin), pz=0;
           
            int neg=0;
            if(ax[pz]=='-')
            {
                        neg=1;
                        if(++pz==DIM)fread(ax, 1, DIM, stdin),pz=0;
            }
         
            while(ax[pz]>='0' && ax[pz]<='9')
            {
                        x=x*10+ax[pz]-'0';
                         if(++pz==DIM)fread(ax,1, DIM, stdin),pz=0;
            }
            if(neg) x=-x;
}


struct point { int x, y;point(){}; point(int a, int b){x=a;y=b;};};

point a[N];
int n,m;

inline long long distanta(point a, point b)
{
	return (long long)(a.x-b.x)*(a.x-b.x)+(long long)(a.y-b.y)*(a.y-b.y);
}

struct nod { int x, y;bool dir; nod *l, *r;};

struct cmp1{
	bool operator()(const point &a, const point &b)const
	{
		if(a.x < b.x) return 1;
		return 0;
	}
};

struct cmp2{
	bool operator()(const point &a, const point &b)const
	{
		if(a.y < b.y) return 1;
		return 0;
	}
};

typedef nod* kd;

kd R;

//point b[N];

kd build(int l, int r,int dir)
{
	if(l >= r) 
	{
		kd t=new nod;
		t->x=a[l].x;
		t->y=a[l].y;
		t->dir=dir;
		t->l=t->r=0;
		return t;
	}
	
	int m=(l+r)>>1;
	if(dir)
	{	
		nth_element(a+l, a+m,a+r+1, cmp1());
	
	}
	
	else
	{		
		nth_element(a+l,a+m, a+r+1, cmp2());
    	}
	
	

	kd t=new nod;
	t->x=a[m].x;
	t->y=a[m].y;
	t->dir=dir;
	t->l=build(l, m-1, dir^1);
	t->r=build(m+1, r, dir^1);
	
	return t;
}
void read()
{
	freopen("forum.in","r",stdin);
	cit(n);cit(m);
	int i;
	for(i=1;i<=n;++i) cit(a[i].x), cit(a[i].y);
	
}

int T;
void ino(kd &n,int t)
{
	if(n == 0) return;
//	printf("(%d %d %d) ", n->x, n->y,n->dir);
	ino(n->l,t+1);
	ino(n->r,t+1);
	//printf("(%d %d) ", n->x, n->y);
	if(T<t)T=t;
}

long long dist=0x3f3f3f3f;
inline void query(kd n, point P)
{
	if(n == 0) return;
	
	if(n->dir == 1)
	{
		if(P.x <= n->x) query(n->l, P);
		else query(n->r, P);
	}
	else
	{
		if(P.y <= n->y) query(n->l, P);
		else query(n->r, P);
	}
	 
	if(distanta(P, point(n->x, n->y)) < dist)
		dist=distanta(P, point(n->x, n->y));
	
	
}

inline int intersect(int X0, int Y0, int X1, int Y1, point P, long long R)
{
	if(P.x>=X0 && P.x <= X1 && P.y >= Y0 && P.y <=Y1) return 1;
	if(P.y>=Y0 && P.y<=Y1 && distanta(point(X0, P.y), P) <=R) return 1;
	if(P.y>=Y0 && P.y<=Y1 && distanta(point(X1, P.y), P) <=R) return 1;
	if(P.x>=X0 && P.x<=X1 && distanta(point(P.x, Y0), P) <=R) return 1;
	if(P.x>=X0 && P.x<=X1 && distanta(point(P.x, Y1), P) <=R) return 1;
	
	///if(distanta(point(X1, (Y1+Y0)>>1), P) <=R) return 1;
	//if(distanta(point((X1+X0)>>1, Y0), P) <=R) return 1;
	//if(distanta(point((X1+X0)>>1, Y1), P) <=R) return 1;
		
	return 0;
	
	if(distanta(point(X0, Y0), P) <= R) return 1;
	if(distanta(point(X1, Y0), P) <=R ) return 1;
	if(distanta(point(X0, Y1), P) <=R ) return 1;
	if(distanta(point(X1, Y1), P) <=R ) return 1;

	return 0;
}

int nr;

inline void quer(kd n,point P, int X0, int Y0, int X1, int Y1)
{
	//++nr;
	if(n == 0) return ;
	
	long long d=distanta(P, point(n->x, n->y));
	if(dist > d) dist=d;
	if(dist <= distanta(P, point(0,0))) { return ;}
	
	
		if( n->dir == 1)
	{
		if(intersect(X0, Y0, n->x, Y1,P, dist)) quer(n->l, P, X0, Y0,n->x, Y1);
		if(intersect(n->x, Y0, X1, Y1, P, dist)) quer(n->r, P,n->x,Y0, X1, Y1);
	
	}
	else
	{
		if(intersect(X0, Y0, X1, n->y, P, dist)) quer(n->l, P, X0, Y0, X1, n->y);
		if(intersect(X0, n->y, X1, Y1, P, dist)) quer(n->r ,P,X0, n->y, X1, Y1);
		
	}

	
}

struct cmp{
	bool operator()(const point &a, const point &b)const
	{
		if(a.x < b.x) return 1;
		return 0;
		
	}
};
int main()
{
	freopen("cutii.out","w",stdout);
	//read();
	n=100000;
	srand(time(0));
	int i;
	for(i=1;i<=n;++i)
	{
		a[i].x=(rand()%100)*300, a[i].y=(rand()%100)*300;
		if(rand()&1) a[i].x=-a[i].x;
		if(rand()&1) a[i].y=-a[i].y;
	}

//	sort(a+1, a+n+1,cmp());
	double s=clock();
	R=build(1,n,1);
	
	long long D;
	int j,cnt,t;
	point P;
	m=100000;
	int Sol=0;
	
	for(i=1;i<=m;++i)
	{
		P.x=rand()%30000;
		P.y=rand()%30000;
		if(rand()&1) P.x=-P.x;
		if(rand()&1) P.y=-P.y;
	//	cit(P.x); cit(P.y);
		
		
		t=find(P.x, P.y);
		if(t  != -1) 
		{
		    if(t) printf("DA\n");
		    else printf("NU\n");
		

		}
		else
			
		{

		
		dist=0x3f3f3f3f;
		query(R, P);
	
		//int d=dist;
		//nr=0;
		quer(R,P,-32000, -32000, 32000, 32000);
		
		//fprintf(stderr,"%d %d\n", nr,dist);
		//if(d!=dist) printf("damn\n");
		D=distanta(P, point(0,0));
	//	printf("%d %d\n", dist, D);
		
//		int SQ=(int) sqrt((double)D);
		if(dist<=D) { insert(P.x, P.y, 0); printf("NU\n");}
		else  { insert(P.x, P.y, 1);printf("DA\n");}
		}
		
	}
	
	//for(i=1;i<=100000;++i) query(R, point(rand(), rand()));
//	fprintf(stderr,"%lf\n", (clock()-s)/(double)CLOCKS_PER_SEC);
	//ino(R,0);
	//printf("%d\n", T);
	return 0;
}