[hdu5033]单调队列
题意:x轴上有n棵树,询问你站在某个点的视角。从左至右,单调队列(类似凸包)维护下。我强迫症地写了个模板QAQ
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }