zoukankan      html  css  js  c++  java
  • hdu4742

    题意:给定3维的n(<=100000)个点,求最长不下降子序列长度(对于1和2两个点,2可以放在1后面,x1<=x2,y1<=y2,z1<=z2 ),并求出有多少种方案。

    思路:裸的cdq分治。。

             首先可以先对x排序,就降成二维了。。

             定义solve(l,r)为处理[l,r]的区间

             那么solve(l,r)为如下:{

                    solve(l, mid)

                    对于l,r的点按照y关键字排序

                    然后从左到右(y增大方向)扫描,对于(l, mid)的点插入将值插入z离散化的数据结构里维护,

                    对于(mid+1,r)的点直接查询数据结果,更改结果

                    清空数据结构。

                   solve(mid+1, r)

            }

           大致就这样,可以做到nlog^2n的复杂度。。数据结构可以选用bit或者线段树。。不过大家都选用bit吧。。

           cdq果然强大,还需慢慢体会呀。。

      1 /*
      2  * Author:  Yzcstc
      3  * Created Time:  2014年10月03日 星期五 22时57分13秒
      4  * File Name: hdu4742.cpp
      5  */
      6 #include <iostream>
      7 #include <cstdio>
      8 #include <cstdlib>
      9 #include <cstring>
     10 #include <cmath>
     11 #include <algorithm>
     12 #include <string>
     13 #include <vector>
     14 #include <stack>
     15 #include <queue>
     16 #include <set>
     17 #include <utility>
     18 #define M0(x) memset(x, 0, sizeof(x))
     19 #define MP make_pair
     20 #define PB push_back
     21 #define repf(i, a, b) for (int i = (a); i <= (b); ++i)
     22 #define Inf 0x3fffffff
     23 #define eps 1e-8
     24 #define pi acos(-1)
     25 #define maxn 120000
     26 #define X first
     27 #define Y second
     28 using namespace std;
     29 typedef pair<int, int> pii;
     30 struct point{
     31     int x, y, z,id;
     32     void input(){
     33         scanf("%d%d%d", &x, &y, &z);
     34     }
     35     bool operator<(const point& p) const{
     36         if (x < p.x) return true;
     37         if (x == p.x && y < p.y) return true;
     38         if (x == p.x && y == p.y && z < p.z) return true;
     39         return false;
     40     }
     41 } p[maxn], pt[maxn];
     42 int t[maxn], n, m;
     43 pii dp[maxn], v[maxn], zero(0, 0);
     44 
     45 void init(){
     46      scanf("%d", &n);
     47      for (int i = 1; i <= n; ++i)
     48           p[i].input(), t[i-1] = p[i].z;
     49      sort(p + 1, p + 1 + n);
     50      sort(t, t + n);
     51      m = unique(t, t + n) - t;
     52 //     cout << m << endl;
     53      for (int i = 1; i <= n; ++i)
     54           p[i].z = lower_bound(t, t + m, p[i].z) - t + 1;
     55 //     repf(i, 1, n) printf("%d
    " ,p[i].z);
     56      for (int i = 1; i <= n; ++i)
     57           p[i].id = i;
     58 }
     59 
     60 /** BIT **/
     61 inline int lowbit(const int& x){
     62      return x & (-x); 
     63 }
     64 
     65 inline void update(pii &a, const pii &b){
     66      if (a.X < b.X) a = b;
     67      else if (a.X == b.X) a.Y += b.Y;
     68 }
     69 
     70 void modify(int x, const pii& val){
     71      for ( ; x <= m; x += lowbit(x))
     72          update(v[x], val);
     73 }
     74 
     75 pii query(int x){
     76      pii ret(0, 0);
     77      for ( ; x > 0 ; x -= lowbit(x))
     78           update(ret, v[x]);
     79      return ret;
     80 }
     81 
     82 void recover(int x){
     83      for (; x <= m; x += lowbit(x))
     84           v[x] = zero;
     85 }
     86 /** BIT-end **/
     87 /** Divide and conquer**/
     88 pii tmp;
     89 void solve(const int& l,const int& r){
     90      if (l == r) return;
     91      int mid = (l + r) >> 1;
     92      solve(l, mid);
     93      int sz = 0;
     94      for (int i = l; i <= r; ++i)
     95          pt[sz] = p[i], pt[sz++].x = 0;
     96      sort(pt, pt+sz);
     97      for (int i = 0; i < sz; ++i)
     98          if (pt[i].id <= mid)
     99                modify(pt[i].z, dp[pt[i].id]);
    100          else 
    101                tmp = query(pt[i].z), ++tmp.X, update(dp[pt[i].id], tmp);
    102      for (int i = 0; i < sz; ++i)
    103          if (pt[i].id <= mid)
    104                recover(pt[i].z);
    105      solve(mid + 1, r); 
    106 }
    107 
    108 void solve(){
    109      for (int i = 1; i <= n; ++i)
    110           dp[i].X = dp[i].Y = 1;
    111      solve(1, n);
    112      pii ans(0, 0);
    113      for (int i = 1; i <= n; ++i)
    114          update(ans, dp[i]); // printf("i = %d: %d %d
    ", i, dp[i].first, dp[i].second);
    115      printf("%d %d
    ", ans.X, ans.Y);
    116 }
    117 
    118 int main(){
    119  //   freopen("a.in", "r", stdin);
    120 //    freopen("a.out", "w", stdout);
    121     int cas;
    122     scanf("%d", &cas);
    123     while (cas--){
    124          init();
    125          solve(); 
    126     }
    127     return 0;
    128 }
    View Code

                 

  • 相关阅读:
    ORACLE 删除重复的数据
    Linux查看某个文件 单个字符的 个数
    通过虚拟机增加Linux的磁盘(分区容量)
    redheat7 sd 0:0:0:0: [sda] Assuming drive cache: write through(未解决)
    安装数据库Typical path for xclock: /usr/X11R6/bin/xclock 错误问题
    解决Visual Studio 2015启动慢的问题
    使用Discuz!自带参数防御CC攻击以及原理
    mysql 去除特殊字符和前后空白字符
    最新版的Chrome 69.0 设置始终开启flash而不是先询问
    DNS_PROBE_FINISHED_NXDOMAIN 问题解决
  • 原文地址:https://www.cnblogs.com/yzcstc/p/4005522.html
Copyright © 2011-2022 走看看