[hdu5033]单调队列

题意:x轴上有n棵树,询问你站在某个点的视角。从左至右,单调队列(类似凸包)维护下。我强迫症地写了个模板QAQ

  1 #include <iostream>

  2 #include <cstdio>

  3 #include <algorithm>

  4 #include <cstdlib>

  5 #include <cstring>

  6 #include <map>

  7 #include <queue>

  8 #include <deque>

  9 #include <cmath>

 10 #include <vector>

 11 #include <ctime>

 12 #include <cctype>

 13 #include <set>

 14 

 15 using namespace std;

 16 

 17 #define mem0(a) memset(a, 0, sizeof(a))

 18 #define lson l, m, rt << 1

 19 #define rson m + 1, r, rt << 1 | 1

 20 #define define_m int m = (l + r) >> 1

 21 #define Rep(a, b) for(int a = 0; a < b; a++)

 22 #define lowbit(x) ((x) & (-(x)))

 23 #define constructInt4(name, a, b, c, d) name(int a = 0, int b = 0, int c = 0, int d = 0): a(a), b(b), c(c), d(d) {}

 24 #define constructInt3(name, a, b, c) name(int a = 0, int b = 0, int c = 0): a(a), b(b), c(c) {}

 25 #define constructInt2(name, a, b) name(int a = 0, int b = 0): a(a), b(b) {}

 26 

 27 typedef double db;

 28 typedef long long LL;

 29 typedef pair<int, int> pii;

 30 typedef multiset<int> msi;

 31 typedef multiset<int>::iterator msii;

 32 typedef set<int> si;

 33 typedef set<int>::iterator sii;

 34 typedef vector<int> vi;

 35 

 36 const int dx[8] = {1, 0, -1, 0, 1, 1, -1, -1};

 37 const int dy[8] = {0, -1, 0, 1, -1, 1, 1, -1};

 38 const int maxn = 1e5 + 7;

 39 const int maxm = 1e5 + 7;

 40 const int maxv = 1e7 + 7;

 41 const int MD = 1e9 +7;

 42 const int INF = 1e9 + 7;

 43 const double PI = acos(-1.0);

 44 const double eps = 1e-10;

 45 

 46 struct Point {

 47     int x, y;

 48     bool operator < (const Point &opt) const {

 49         return x < opt.x || x == opt.x && y < opt.y;

 50     }

 51     double abs() {

 52         return sqrt((double)x * x + (double)y * y);

 53     }

 54     Point operator - (const Point &opt) const {

 55         return Point(x - opt.x, y - opt.y);

 56     }

 57     double operator * (const Point &opt) const {

 58         return (double)x * opt.x + (double)y * opt.y;

 59     }

 60     constructInt2(Point, x, y);

 61     void inp() {

 62         scanf("%d %d", &x, &y);

 63     }

 64     void outp() {

 65         printf("(%d, %d), ", x, y);

 66     }

 67 };

 68 

 69 bool cmp(const pii &a, const pii &b) {

 70     return a.first < b.first;

 71 }

 72 

 73 double Cross(const Point &a, const Point &b) {

 74     return (double)a.x * b.y - (double)a.y * b.x;

 75 }

 76 

 77 template<class T> struct MonotoneQueue{

 78     deque<T> Q;

 79     MonotoneQueue<T>() { Q.clear(); }

 80     T back() { return Q.back(); }

 81     T back2() { if (Q.size() < 2) return T(); return *(Q.end() - 2); }

 82     T front() { return Q.front(); }

 83     void clear() { Q.clear(); }

 84     bool empty() { return Q.empty(); }

 85     void add_back(T x) { while (!empty() && !(back() - back2() < x - back2())) Q.pop_back(); Q.push_back(x); }

 86     void pop_front() { Q.pop_front(); }

 87 };

 88 

 89 double toDegree(double x) { return x * 180.0 / PI; }

 90 

 91 Point p[maxn], L[maxn], R[maxn];

 92 pii qry[maxn];

 93 int n, m;

 94 

 95 struct Node {

 96     Point dot;

 97     bool operator < (const Node &a) const {

 98         return Cross(dot, a.dot) < eps;

 99     }

100     Node operator - (const Node &opt) const {

101         return Node(dot - opt.dot);

102     }

103     Node(Point dot = Point()): dot(dot) {}

104 };

105 MonotoneQueue<Node> DQ;

106 

107 void work(Point a[]) {

108     DQ.clear();

109     DQ.add_back(p[0]);

110     int now = 1;

111     for (int i = 0; i < m; i++) {

112         while (now < n && p[now].x < qry[i].first) {

113             DQ.add_back(Node(p[now++]));

114         }

115         DQ.add_back(Node(Point(qry[i].first, 0)));

116         a[qry[i].second] = (DQ.back2() - DQ.back()).dot;

117     }

118 }

119 

120 int main() {

121     //freopen("in.txt", "r", stdin);

122     int T, cas = 0;

123     cin >> T;

124     while (T--) {

125         cin >> n;

126         for (int i = 0; i < n; i++) {

127             p[i].inp();

128         }

129         sort(p, p + n);

130         cin >> m;

131         for (int i = 0, x; i < m; i++) {

132             scanf("%d", &x);

133             qry[i] = make_pair(x, i);

134         }

135         sort(qry, qry + m, cmp);

136 

137         work(L);

138 

139         for (int i = 0; i < n; i++) {

140             p[i].x = maxv - p[i].x;

141         }

142         sort(p, p + n);

143         for (int i = 0; i < m; i++) {

144             qry[i].first = maxv - qry[i].first;

145         }

146         sort(qry, qry + m, cmp);

147 

148         work(R);

149         for (int i = 0; i < m; i++) {

150             R[i].x = -R[i].x;

151         }

152 

153         printf("Case #%d:\n", ++cas);

154         for (int i = 0; i < m; i++) {

155             printf("%.10f\n", toDegree(acos(L[i] * R[i] / L[i].abs() / R[i].abs())));

156         }

157     }

158     return 0;

159 }
View Code

 

你可能感兴趣的:(HDU)