bzoj 3718

题意:戳这里

思路:很容易发现对于一个车能否移动到最终的位置只要判断路径中得最大高度与自身高端之和是否>w即可。

         那么就可以转化为逆序对得最大数问题。。即对于每一辆车,判断有那些最初在他前面,而最终却在他后面的            车的与他的高度和是否>w即可。。树状数组维护。。

code:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define M0(a) memset(a, 0, sizeof(a))
 4 #define repf(i, a, b) for (int i = (a); i <= (b); ++i)
 5 const int maxn = 120000;
 6 struct trangle{
 7      int x1, y1, x2, y2, p, h;
 8      void input(int p){
 9           this->p = p;
10           scanf("%d%d%d%d", &x1, &x2, &y1, &y2);
11           if (x1 > x2) swap(x1, x2);
12           if (y1 > y2) swap(y1, y2);
13           h = y2 - y1;
14      }
15      bool operator<(const trangle& p) const{
16           return x1 == p.x1 ? x2 < p.x2 : x1 < p.x1;
17      }
18 } f[maxn], s[maxn];
19 int v[maxn], n, pos[maxn], w;
20 inline int lowbit(const int& x){
21     return x & (-x);
22 }
23  
24 void update(int x,const int& val){
25      for (;x <= n; x += lowbit(x))
26            v[x] = max(v[x], val);
27 }
28  
29 int query(int x){
30     int res = 0;
31     for (;x>0; x-= lowbit(x))
32         res = max(res, v[x]);
33     return res;
34 }
35  
36 void solve(){
37     scanf("%d%d", &n, &w);
38 //    cout << w << endl;
39     repf(i, 1, n) f[i].input(i); 
40     repf(i, 1, n) s[i].input(i);
41     sort(f + 1, f + 1 + n);
42     sort(s + 1, s + 1 + n);
43     M0(pos), M0(v);
44     repf(i, 1, n) pos[f[i].p] = i;
45     bool ok = 1;
46     for (int i = n; i >= 1; --i){
47          if (!ok) break;
48          if (query(pos[s[i].p]) + s[i].h > w) ok = 0;
49          update(pos[s[i].p], s[i].h);
50     }
51     puts(ok ? "TAK" : "NIE");
52      
53 }
54  
55 int main(){
56 //    freopen("a.in", "r", stdin);
57     int _;
58     scanf("%d", &_);
59     while (_--){
60          solve(); 
61     }
62 }
View Code
原文地址:https://www.cnblogs.com/yzcstc/p/4074552.html