Advertisement
Guest User

Untitled

a guest
Mar 19th, 2018
138
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.73 KB | None | 0 0
  1. #include <cstdio>
  2. #include <cassert>
  3. #include <algorithm>
  4. #include <vector>
  5. #include <set>
  6. #include "testlib.h"
  7. using namespace std;
  8.  
  9. typedef long long llong;
  10.  
  11. const int N = 100000;
  12. const int Q = 500000;
  13. const int MAX = 200000000;
  14.  
  15. int line[3 * N];
  16.  
  17. struct vt
  18. {
  19. static const int VMAX = 1000000000;
  20. int x, y;
  21. vt(){}
  22. vt(int _x, int _y)
  23. {
  24. x = _x, y = _y;
  25. if (abs(x) > VMAX || abs(y) > VMAX)
  26. {
  27. fprintf(stderr, "Program is about to overflow in internal calculations, sorry =( change VMAX constant if you are sure what you're doing");
  28. throw 42;
  29. }
  30. }
  31. friend vt operator -(vt a, vt b)
  32. {
  33. return vt(a.x - b.x, a.y - b.y);
  34. }
  35. friend llong operator ^(vt a, vt b)
  36. {
  37. return (llong)a.x * b.y - (llong)b.x * a.y;
  38. }
  39. friend vt operator ~(vt a)
  40. {
  41. return vt(a.y, -a.x);
  42. }
  43. friend vt operator /(vt a, int k)
  44. {
  45. assert(a.x % k == 0 && a.y % k == 0);
  46. return vt(a.x / k, a.y / k);
  47. }
  48. char* to_string()
  49. {
  50. char* buf = new char[50];
  51. sprintf(buf, "(%d, %d)", x, y);
  52. return buf;
  53. }
  54. };
  55.  
  56. struct CheckNonIntersection
  57. {
  58.  
  59. typedef vector<pair<vt, vt> > SV;
  60.  
  61. SV S;
  62.  
  63. char sign(llong x)
  64. {
  65. return (x > 0) - (x < 0);
  66. }
  67.  
  68. inline bool inter(vt a, vt b, vt c, vt d)
  69. {
  70. return (sign((b - a) ^ (c - a)) * sign((b - a) ^ (d - a))) + (sign((d - c) ^ (a - c)) * sign((d - c) ^ (b - c))) < 0;
  71. }
  72.  
  73. inline llong gcd(llong a, llong b)
  74. {
  75. if (a < 0)
  76. a = -a;
  77. if (b < 0)
  78. b = -b;
  79. while (b)
  80. a %= b, swap(a, b);
  81. return a;
  82. }
  83.  
  84. static inline bool cmp_lex(vt a, vt b)
  85. {
  86. return (a.x != b.x) ? a.x < b.x : a.y < b.y;
  87. }
  88.  
  89. vt find_new_basis()
  90. {
  91. vector<vt> used;
  92. for (int i = 0; i < S.size(); i++)
  93. {
  94. vt v = S[i].second - S[i].first;
  95. llong g = gcd(v.x, v.y);
  96. assert(g != 0);
  97. v = v / g;
  98. for (int it = 0; it < 4; it++, v = ~v)
  99. if (v.x >= 0 && v.y >= 0)
  100. used.push_back(v);
  101. }
  102. sort(used.begin(), used.end(), cmp_lex);
  103. vt b;
  104. for (int s = 1; s <= 1000; s++)
  105. {
  106. for (int y = 0; y <= s; y++)
  107. {
  108. int x = s - y;
  109. if (gcd(x, y) != 1)
  110. continue;
  111. if (binary_search(used.begin(), used.end(), vt(y, x), cmp_lex))
  112. continue;
  113. return vt(x, y);
  114. }
  115. }
  116. assert(false);
  117. }
  118.  
  119. vt apply_basis(vt v, vt b)
  120. {
  121. return vt(b.x * v.x - b.y * v.y, b.y * v.x + b.x * v.y);
  122. }
  123.  
  124. struct cmp_by_x
  125. {
  126. vector<pair<vt, vt> >& S;
  127. cmp_by_x(vector<pair<vt, vt> > &_S) : S(_S) {}
  128. inline bool operator()(int a, int b)
  129. {
  130. int u = (a >= 0) ? S[a].first.x : S[~a].second.x;
  131. int v = (b >= 0) ? S[b].first.x : S[~b].second.x;
  132. if (u != v)
  133. return u < v;
  134. else
  135. return (a >= 0) < (b >= 0);
  136. }
  137. };
  138.  
  139. struct cmp_by_y
  140. {
  141. int& x;
  142. vector<pair<vt, vt> >& S;
  143. cmp_by_y(int& _x, vector<pair<vt, vt> >& _S) : x(_x), S(_S)
  144. {
  145. for (int i = 0; i < S.size(); i++)
  146. assert(S[i].first.x < S[i].second.x);
  147. }
  148. inline bool operator ()(int i, int j)
  149. {
  150. llong iu = (llong)(S[i].second.x - x) * S[i].first.y + (llong)(x - S[i].first.x) * S[i].second.y;
  151. llong ju = (llong)(S[j].second.x - x) * S[j].first.y + (llong)(x - S[j].first.x) * S[j].second.y;
  152. int id = (S[i].second.x - S[i].first.x);
  153. int jd = (S[j].second.x - S[j].first.x);
  154. if (abs(iu / id - ju / jd) >= 2)
  155. return iu / id < ju / jd;
  156. else
  157. return iu * jd - ju * id < 0;
  158. }
  159. };
  160.  
  161. inline void check_inter(int i, int j)
  162. {
  163. quitif(inter(S[i].first, S[i].second, S[j].first, S[j].second), _fail, "Segments from lines %d and %d are intersecting", line[i], line[j]);
  164. }
  165.  
  166. CheckNonIntersection(vector<pair<vt, vt> > _S)
  167. {
  168. S = _S;
  169. vt u = find_new_basis();
  170. for (int i = 0; i < S.size(); i++)
  171. {
  172. S[i].first = apply_basis(S[i].first, u), S[i].second = apply_basis(S[i].second, u);
  173. if (S[i].first.x > S[i].second.x)
  174. swap(S[i].first, S[i].second);
  175. S[i].first.x *= 2, S[i].second.x *= 2;
  176. assert(S[i].first.x != S[i].second.x);
  177. }
  178. int x;
  179. multiset<int, cmp_by_y> A(cmp_by_y(x, S));
  180. vector<int> ev(2 * S.size());
  181. for (int i = 0; i < S.size(); i++)
  182. ev[2 * i] = i, ev[2 * i + 1] = ~i;
  183. sort(ev.begin(), ev.end(), cmp_by_x(S));
  184. vector<multiset<int, cmp_by_y>::iterator> pos(S.size(), A.end());
  185. for (int i = 0; i + 1 < ev.size(); i++)
  186. {
  187. int v = ev[i], w = ev[i + 1];
  188. int ax = (v >= 0) ? S[v].first.x : S[~v].second.x;
  189. int bx = (w >= 0) ? S[w].first.x : S[~w].second.y; // !!!!!!!!!!
  190. x = (ax + bx) / 2;
  191. if (v >= 0)
  192. {
  193. pos[v] = A.insert(v);
  194. multiset<int, cmp_by_y>::iterator it = pos[v];
  195. if (it != A.begin())
  196. check_inter(v, *(--it)), it = pos[v];
  197. if ((++it) != A.end())
  198. check_inter(v, *it);
  199. }
  200. else
  201. {
  202. multiset<int, cmp_by_y>::iterator itl = pos[~v], itr = pos[~v];
  203. if (itl != A.begin() && (++itr) != A.end())
  204. check_inter(*(--itl), *itr);
  205. A.erase(pos[~v]);
  206. pos[~v] = A.end();
  207. }
  208. }
  209. }
  210. };
  211.  
  212. vector<int> E[3 * N];
  213. vt P[N];
  214.  
  215. struct cmp_by_ang
  216. {
  217. vt O;
  218. cmp_by_ang(vt _O) { O = _O; }
  219. inline bool operator()(int a, int b)
  220. {
  221. vt u = P[a] - O, v = P[b] - O;
  222. int pu = (u.y > 0 || (u.x > 0 && u.y == 0));
  223. int pv = (v.y > 0 || (v.x > 0 && v.y == 0));
  224. if (pu != pv)
  225. return pu > pv;
  226. return (u ^ v) >= 0;
  227. }
  228. };
  229.  
  230. bool was[N];
  231.  
  232. void DFS(int x)
  233. {
  234. was[x] = true;
  235. for (int i = 0; i < E[x].size(); i++)
  236. {
  237. int y = E[x][i];
  238. if (!was[y])
  239. DFS(y);
  240. }
  241. }
  242.  
  243. set<pair<int, int> > points;
  244. set<pair<int, int> > edges;
  245. int main()
  246. {
  247. registerValidation();
  248. int n, k;
  249. n = inf.readInt(1, N);
  250. inf.readEoln();
  251. for (int i = 0; i < n; i++)
  252. {
  253. int x = inf.readInt(-MAX, MAX);
  254. inf.readSpace();
  255. int y = inf.readInt(-MAX, MAX);
  256. inf.readEoln();
  257. P[i] = vt(x, y);
  258. quitif(!points.insert(make_pair(x, y)).second, _fail, "point %d: %d %d is already used", i, P[i].x, P[i].y);
  259. }
  260. k = inf.readInt(1, Q);
  261. inf.readEoln();
  262. vector<pair<vt, vt> > VE;
  263. for (int i = 0; i < k; i++)
  264. {
  265. int t = inf.readInt(0, 1);
  266. inf.readSpace();
  267. int a = inf.readInt(0, n - 1);
  268. inf.readSpace();
  269. int b = inf.readInt(0, n - 1);
  270. if (t == 1)
  271. {
  272. quitif(!edges.insert(make_pair(a, b)).second, _fail, "query %d: edge %d %d is already on the picture", i, a, b);
  273. quitif(!edges.insert(make_pair(b, a)).second, _fail, "query %d: edge %d %d is already on the picture", i, a, b);
  274. line[VE.size()] = i;
  275. VE.push_back(make_pair(P[a], P[b]));
  276. E[a].push_back(b);
  277. E[b].push_back(a);
  278. }
  279. else
  280. quitif(edges.find(make_pair(a, b)) == edges.end(), _fail, "query %d: edge %d %d isn't presented yet", i, a, b);
  281. quitif(a == b, _fail, "query %d: equal numbers in query", i);
  282. inf.readEoln();
  283. }
  284. inf.readEof();
  285. try
  286. {
  287. new CheckNonIntersection(VE);
  288. }
  289. catch (int e)
  290. {
  291. assert(e == 42);
  292. }
  293. for (int i = 0; i < n; i++)
  294. sort(E[i].begin(), E[i].end(), cmp_by_ang(P[i]));
  295. DFS(0);
  296. for (int i = 0; i < n; i++)
  297. quitif(!was[i], _fail, "point %d isn't connected with 0", i);
  298.  
  299. for (int i = 0; i < n; i++)
  300. {
  301. for (int j = 0; j < E[i].size(); j++)
  302. {
  303. int u = E[i][j];
  304. int v = E[i][(j + 1) % E[i].size()];
  305. if (((P[u] - P[i]) ^ (P[v] - P[i])) <= 0)
  306. continue;
  307. quitif(edges.find(make_pair(u, v)) == edges.end(), _fail, "there are edges %d %d and %d %d but no edge %d %d", i, u, i, v, u, v);
  308. }
  309. }
  310. return 0;
  311. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement