답안 #210524

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
210524 2020-03-17T15:17:42 Z arnold518 Dragon 2 (JOI17_dragon2) C++14
60 / 100
4000 ms 23344 KB
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

const int MAXN = 3e4;

struct Point { ll x, y; };
Point operator + (const Point &p, const Point &q) { return {p.x+q.x, p.y+q.y}; }
Point operator - (const Point &p, const Point &q) { return {p.x-q.x, p.y-q.y}; }

ll ccw(Point p, Point q) { return p.x*q.y-p.y*q.x; }
ll ccw(Point p, Point q1, Point q2) { return ccw(q1-p, q2-p); }

int N, M, Q;
vector<Point> P[MAXN+10];
Point A, B;
map<pii, ll> memo;

struct Node
{
	int val;
	Node *lc, *rc;
	Node() : val(0), lc(NULL), rc(NULL) {}
};

void makeTree(Node *node, int tl, int tr)
{
	if(tl==tr) return;
	int mid=tl+tr>>1;
	node->lc=new Node();
	node->rc=new Node();
	makeTree(node->lc, tl, mid);
	makeTree(node->rc, mid+1, tr);
}

bool cmpA(const Point &p, const Point &q)
{
	if((A.x<p.x || (A.x==p.x && A.y>p.y)) && (A.x<q.x || (A.x==q.x && A.y>q.y))) return ccw(A, p, q)>0;
	if((A.x>p.x || (A.x==p.x && A.y<p.y)) && (A.x>q.x || (A.x==q.x && A.y<q.y))) return ccw(A, p, q)>0;
	if((A.x<p.x || (A.x==p.x && A.y>p.y)) && (A.x>q.x || (A.x==q.x && A.y<q.y))) return true;
	if((A.x>p.x || (A.x==p.x && A.y<p.y)) && (A.x<q.x || (A.x==q.x && A.y>q.y))) return false;
}

bool cmpB(const Point &p, const Point &q)
{
	if((B.x<p.x || (B.x==p.x && B.y>p.y)) && (B.x<q.x || (B.x==q.x && B.y>q.y))) return ccw(B, p, q)>0;
	if((B.x>p.x || (B.x==p.x && B.y<p.y)) && (B.x>q.x || (B.x==q.x && B.y<q.y))) return ccw(B, p, q)>0;
	if((B.x<p.x || (B.x==p.x && B.y>p.y)) && (B.x>q.x || (B.x==q.x && B.y<q.y))) return true;
	if((B.x>p.x || (B.x==p.x && B.y<p.y)) && (B.x<q.x || (B.x==q.x && B.y>q.y))) return false;
}

struct Data
{
	int S;
	vector<Point> VA, VB;
	vector<pii> V;
	vector<Node*> tree;

	Node *addTree(Node *node, int tl, int tr, int pos)
	{
		if(pos<tl || tr<pos) return node;
		Node *ret=new Node();
		if(tl==tr)
		{
			ret->val=node->val+1;
			return ret;
		}
		int mid=tl+tr>>1;
		ret->lc=addTree(node->lc, tl, mid, pos);
		ret->rc=addTree(node->rc, mid+1, tr, pos);
		ret->val=(ret->lc->val)+(ret->rc->val);
		return ret;
	}

	int query(Node *nodel, Node *noder, int tl, int tr, int l, int r)
	{
		if(tr<l || r<tl) return 0;
		if(l<=tl && tr<=r) return (noder->val)-(nodel->val);
		int mid=tl+tr>>1;
		return query(nodel->lc, noder->lc, tl, mid, l, r)+query(nodel->rc, noder->rc, mid+1, tr, l, r);
	}

	void init()
	{
		int i, j;
		S=VA.size();
		if(S==0) return;
		sort(VA.begin(), VA.end(), cmpA);
		sort(VB.begin(), VB.end(), cmpB);

		vector<pair<Point, int>> VAT, VBT;
		for(i=0; i<S; i++) VAT.push_back({VA[i], i});
		for(i=0; i<S; i++) VBT.push_back({VB[i], i});
		sort(VAT.begin(), VAT.end(), [&](const pair<Point, int> &p, const pair<Point, int> &q) { return pll(p.first.x, p.first.y)<pll(q.first.x, q.first.y); });
		sort(VBT.begin(), VBT.end(), [&](const pair<Point, int> &p, const pair<Point, int> &q) { return pll(p.first.x, p.first.y)<pll(q.first.x, q.first.y); });

		for(i=0; i<S; i++)
		{
			int x=VAT[i].second+1, y=VBT[i].second+1;
			//printf("!(%d %d) : %d %d\n", VAT[i].first.x, VAT[i].first.y, x, y);
			V.push_back({x, y});
		}
		sort(V.begin(), V.end());

		tree.push_back(new Node());
		makeTree(tree[0], 1, S);
		for(i=0; i<S; i++)
		{
			tree.push_back(addTree(tree.back(), 1, S, V[i].second));
		}
	}

	int query(Point pxl, Point pxr, Point pyl, Point pyr)
	{
		int i, j;
		if(S==0) return 0;
		int xl=(lower_bound(VA.begin(), VA.end(), pxl, cmpA)-VA.begin())%S+1;
		int xr=(upper_bound(VA.begin(), VA.end(), pxr, cmpA)-VA.begin()-1+S)%S+1;
		int yl=(lower_bound(VB.begin(), VB.end(), pyl, cmpB)-VB.begin())%S+1;
		int yr=(upper_bound(VB.begin(), VB.end(), pyr, cmpB)-VB.begin()-1+S)%S+1;

		//printf("QUERYQUERYNK %d %d %d %d\n", xl, xr, yl, yr);

		if(!(ccw(A, pxl, VA[xl-1])>=0 && ccw(A, VA[xl-1], pxr)>=0)) return 0;
		if(!(ccw(A, pxl, VA[xr-1])>=0 && ccw(A, VA[xr-1], pxr)>=0)) return 0;
		if(!(ccw(B, pyl, VB[yl-1])>=0 && ccw(B, VB[yl-1], pyr)>=0)) return 0;
		if(!(ccw(B, pyl, VB[yr-1])>=0 && ccw(B, VB[yr-1], pyr)>=0)) return 0;

		int ret=0;

		if(xl<=xr)
		{
			if(yl<=yr)
			{
				ret+=query(tree[xl-1], tree[xr], 1, S, yl, yr);
			}
			else
			{
				ret+=query(tree[xl-1], tree[xr], 1, S, yl, S);
				ret+=query(tree[xl-1], tree[xr], 1, S, 1, yr);
			}
		}
		else
		{
			if(yl<=yr)
			{
				ret+=query(tree[0], tree[xr], 1, S, yl, yr);
				ret+=query(tree[xl-1], tree[S], 1, S, yl, yr);
			}
			else
			{
				ret+=query(tree[0], tree[xr], 1, S, yl, S);
				ret+=query(tree[0], tree[xr], 1, S, 1, yr);
				ret+=query(tree[xl-1], tree[S], 1, S, yl, S);
				ret+=query(tree[xl-1], tree[S], 1, S, 1, yr);
			}
		}
		//printf("QUERY %d %d %d %d : %d\n", xl, xr, yl, yr, ret);
		return ret;
	}
};
Data D[MAXN+10];

int main()
{
	int i, j;

	scanf("%d%d", &N, &M);
	for(i=1; i<=N; i++)
	{
		int x, y, w;
		scanf("%d%d%d", &x, &y, &w);
		P[w].push_back({x, y});
	}
	scanf("%lld%lld%lld%lld", &A.x, &A.y, &B.x, &B.y);

	for(i=1; i<=M; i++)
	{
		for(auto it : P[i])
		{
			D[i].VA.push_back(it);
			D[i].VB.push_back(it);
		}
		D[i].init();
		//printf("-> %d\n", i);
	}

	scanf("%d", &Q);
	while(Q--)
	{
		int s, e;
		ll ans=0;
		scanf("%d%d", &s, &e);
		if(true)
		{
			for(auto it : P[s])
			{
				Point pxl, pxr, pyl, pyr;
				pxl=it, pxr={2*A.x-it.x, 2*A.y-it.y};
				pyl=it, pyr={2*B.x-it.x, 2*B.y-it.y};
				if(ccw(A, it, B)<0) swap(pxl, pxr);
				if(ccw(B, it, A)<0) swap(pyl, pyr);
				//printf("%lld %lld / %lld %lld / %lld %lld / %lld %lld -> \n", pxl.x, pxl.y, pxr.x, pxr.y, pyl.x, pyl.y, pyr.x, pyr.y);
				int t=D[e].query(pxl, pxr, pyl, pyr);
				//printf("-> %d\n", t);
				ans+=t;
			}
		}
		printf("%lld\n", ans);
	}
}

Compilation message

dragon2.cpp: In function 'void makeTree(Node*, int, int)':
dragon2.cpp:32:12: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  int mid=tl+tr>>1;
          ~~^~~
dragon2.cpp: In member function 'Node* Data::addTree(Node*, int, int, int)':
dragon2.cpp:71:13: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   int mid=tl+tr>>1;
           ~~^~~
dragon2.cpp: In member function 'int Data::query(Node*, Node*, int, int, int, int)':
dragon2.cpp:82:13: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   int mid=tl+tr>>1;
           ~~^~~
dragon2.cpp: In member function 'void Data::init()':
dragon2.cpp:88:10: warning: unused variable 'j' [-Wunused-variable]
   int i, j;
          ^
dragon2.cpp: In member function 'int Data::query(Point, Point, Point, Point)':
dragon2.cpp:118:7: warning: unused variable 'i' [-Wunused-variable]
   int i, j;
       ^
dragon2.cpp:118:10: warning: unused variable 'j' [-Wunused-variable]
   int i, j;
          ^
dragon2.cpp: In function 'int main()':
dragon2.cpp:169:9: warning: unused variable 'j' [-Wunused-variable]
  int i, j;
         ^
dragon2.cpp: In function 'bool cmpA(const Point&, const Point&)':
dragon2.cpp:45:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^
dragon2.cpp: In function 'bool cmpB(const Point&, const Point&)':
dragon2.cpp:53:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^
dragon2.cpp: In function 'int main()':
dragon2.cpp:171:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  scanf("%d%d", &N, &M);
  ~~~~~^~~~~~~~~~~~~~~~
dragon2.cpp:175:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   scanf("%d%d%d", &x, &y, &w);
   ~~~~~^~~~~~~~~~~~~~~~~~~~~~
dragon2.cpp:178:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  scanf("%lld%lld%lld%lld", &A.x, &A.y, &B.x, &B.y);
  ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
dragon2.cpp:191:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  scanf("%d", &Q);
  ~~~~~^~~~~~~~~~
dragon2.cpp:196:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   scanf("%d%d", &s, &e);
   ~~~~~^~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 13 ms 5772 KB Output is correct
2 Correct 19 ms 5496 KB Output is correct
3 Correct 62 ms 5244 KB Output is correct
4 Correct 89 ms 5880 KB Output is correct
5 Correct 55 ms 5880 KB Output is correct
6 Correct 11 ms 4856 KB Output is correct
7 Correct 11 ms 4856 KB Output is correct
8 Correct 12 ms 5752 KB Output is correct
9 Correct 11 ms 5752 KB Output is correct
10 Correct 11 ms 5624 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 94 ms 23344 KB Output is correct
2 Correct 202 ms 20984 KB Output is correct
3 Correct 71 ms 18680 KB Output is correct
4 Correct 52 ms 15096 KB Output is correct
5 Correct 46 ms 11640 KB Output is correct
6 Correct 73 ms 23316 KB Output is correct
7 Correct 73 ms 23316 KB Output is correct
8 Correct 66 ms 23308 KB Output is correct
9 Correct 51 ms 23064 KB Output is correct
10 Correct 52 ms 23068 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 13 ms 5772 KB Output is correct
2 Correct 19 ms 5496 KB Output is correct
3 Correct 62 ms 5244 KB Output is correct
4 Correct 89 ms 5880 KB Output is correct
5 Correct 55 ms 5880 KB Output is correct
6 Correct 11 ms 4856 KB Output is correct
7 Correct 11 ms 4856 KB Output is correct
8 Correct 12 ms 5752 KB Output is correct
9 Correct 11 ms 5752 KB Output is correct
10 Correct 11 ms 5624 KB Output is correct
11 Correct 94 ms 23344 KB Output is correct
12 Correct 202 ms 20984 KB Output is correct
13 Correct 71 ms 18680 KB Output is correct
14 Correct 52 ms 15096 KB Output is correct
15 Correct 46 ms 11640 KB Output is correct
16 Correct 73 ms 23316 KB Output is correct
17 Correct 73 ms 23316 KB Output is correct
18 Correct 66 ms 23308 KB Output is correct
19 Correct 51 ms 23064 KB Output is correct
20 Correct 52 ms 23068 KB Output is correct
21 Correct 87 ms 23320 KB Output is correct
22 Correct 198 ms 20984 KB Output is correct
23 Correct 1068 ms 18680 KB Output is correct
24 Correct 1123 ms 16248 KB Output is correct
25 Correct 145 ms 13432 KB Output is correct
26 Correct 108 ms 12920 KB Output is correct
27 Correct 47 ms 11640 KB Output is correct
28 Correct 47 ms 11640 KB Output is correct
29 Execution timed out 4082 ms 17492 KB Time limit exceeded
30 Halted 0 ms 0 KB -