[BZOJ2391] Cirno's Melancholy
Question Description
Cirno like frozen frogs when they are idle. Cirno each time a simple polygon is selected from the N nodes fixed in the lake of fog, Cirno uses his ability to freeze all the frogs in the polygon. The lake of fog lives with M frogs, frogs are big and small, so the value of each frog is a positive integer not greater than 10000. Cirno wanted to know the total value of each frozen frog. Because of the limited IQ, cirno the problem to you in the perfect arithmetic classroom. Because of the love of animals, so each frozen frog will be released. That is to say, a frog can be counted more than once.
Input
The first row of 2 positive integers n,m. The following n lines, 2 integers per line xi,yi, represent the coordinates of the I node. The following m lines, 3 integers per line xj,yj,vj, represent the coordinates and values of the J Frog. Line n+m+1 An integer q, which indicates that there is a Q group asking. Each set of queries has 2 rows, the first line an integer s (3<=s<=n), representing the node number of the simple polygon. Second line s positive integer that gives the number of the polygon's node (1--n) clockwise or counterclockwise
Output
Q Line. For each query, each line outputs an integer representing the sum of the frozen frog's value
Input example
4 32 23 57 45 13 4 24 3 76 3 -231 2 341 4 3 2
Output example
9 About
Data size and conventions
For 30% of data,n,m<=100; q<=100
For 60% of data,n,m<=100; q<=10000
For 100% of data,n,m<=1000; q<=10000
-10000<=x,y<=10000; 0<v<=10000
Exercises
The vector is so good!
First introduce a new thing: triangulation. Take this example, we mix two types of points, but the first kind of point weight value is 0. Next, to order all points according to the polar coordinates, then we need to maintain a tot[i][j] representing the origin, I, J these three points of the triangle consists of the points of the weights and, and the provisions: I to J is the polar angle sort positive direction when Tot[i][j] is positive (note the ownership value v > 0), and vice versa Negative. Then in the query for a simple polygon directly to the next two vertices of the tot value added up.
As for how to maintain tot[i][j], you can first determine I and point I as the new origin, and then in the order of the polar angle to a balance tree dot, each time I add j to count the current balance tree with I as the origin and in the vector i->j left vector number, this number is tot[i][j].
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cctype > #include <algorithm> #include <cmath>using namespace Std;int read () {int x = 0, f = 1; char c = GetChar (); w Hile (!isdigit (c)) {if (c = = '-') f =-1; c = GetChar ();} while (IsDigit (c)) {x = x * + C-' 0 '; c = GetChar ();} return x * f;} #define MAXN 2010struct Vec {int x, y; Vec () {}vec (int _, int __): X (_), Y (__) {}bool operator < (const vec& t) const {return T.Y * x-t.x * y? T.Y * x -T.x * Y < 0:x * x + y * y > T.x * t.x + t.y * T.Y;} If a < b then A was on B ' s left side. VEC operator-(const vec& t) const {return Vec (x-t.x, Y-t.y);}} St;struct Point {Vec p; int Val, id; Point () {}point (Vec _1, int _2, int _3): P (_1), Val (_2), id (_3) {}bool operator < (const point& t) const {return P -St < T.p-st; }} ps[maxn];int cp;struct Node {Vec v;int val, R, Siz, sum; Node () {}node (Vec _1, int _2, int _3): V (_1), Val (_2), R (_3) {}} Ns[maxn];int ToT, RT, FA[MAXN], ch[2][maxn];void maintain (int o) {ns[o].siz = 1; ns[o].sum = ns[o].val;for (int i = 0; I < 2; i++) if (Ch[i][o]) Ns[o].siz + = Ns[ch[i][o]].siz, ns[o].sum + = Ns[ch[i][o]].sum;return;} void rotate (int u) {int y = Fa[u], z = fa[y], l = 0, r = 1;if (z) ch[ch[1][z]==y][z] = u;if (ch[1][y] = = u) Swap (L, R); Fa[u] = Z; Fa[y] = u; Fa[ch[r][u]] = y;ch[l][y] = Ch[r][u]; Ch[r][u] = Y;maintain (y); Maintain (U); return;} int insert (int& o, point x, point Org) {if (!o) {ns[o = ++tot] = Node (X.P, X.val, Rand ()); maintain (o); return x.val;} BOOL D = X.P-ORG.P < NS[O].V-ORG.P; D ^= 1;int ans = 0, ls = ch[0][o]? Ns[ch[0][o]].sum:0;if (d) ans + = ls + Ns[o].val;ans + = insert (Ch[d][o], x, ORG); Fa[ch[d][o]] = o;if (Ns[ch[d][o]].r > NS[O].R) {int t = ch[d][o];rotate (t); o = t;} Maintain (o); return ans;} int PID[MAXN], tot[maxn][maxn], N, m;void Init () {sort (PS + 1, PS + CP + 1); for (int i = 1; I <= (CP >> 1); i++) s WAP (Ps[i], ps[cp-i+1]); for (int i = 1; I <= cp i++) if (ps[i].id <= n) pid[ps[i].id] = i;//for (int i = 1; I <= CP; i++) printf ("point[%d]:%d%d\n", I, ps[i].p.x, p S[I].P.Y); for (int i = 1; I <= CP; i++) {memset (FA, 0, sizeof (FA)), memset (CH, 0, sizeof (CH)), RT = ToT = 0;for (int j = i; J <= CP; J + +) {Tot[i][j] = insert (RT, ps[j], ps[i]), if (i! = j) Tot[j][i] =-tot[i][j];//printf ("%d%d:%d\n", I, J, Tot[i][j]);}} return;} int RPS[MAXN], get[maxn];int Main () {n = read (); m = read (); st = Vec ( -10001, -10001); for (int i = 1; I <= n; i++) {int x = Read (), y = Read ();p s[i] = Point (Vec (x, y), 0, i);} for (int i = 1; I <= m; i++) {int x = read (), y = Read (), V = read ();p s[i+n] = Point (Vec (x, y), V, i + N);} CP = n + m;init (), int q = Read (), while (q--) {int t = read (), for (int i = 0; i < T; i++) Rps[i] = Pid[read ()];//for (int i = 0; I < T; i++) printf ("%d%c", Rps[i], I < t-1? ': ' \ n '); int ans = 0;for (int i = 0; i < T; i++) ans + = tot[rps[i]][rps[(i+1)%t]];p rintf ("%d\n", abs (ANS));} return 0;}
By the way to complete the preview of the "vector" job ...
[BZOJ2391] Cirno's Melancholy