• UVALive


    题意:现在有一个点堆, 一开始先给你m个点,然后再用题目中的rand函数生成剩下的n个点,问在这个点堆中可以找到的最长严格递增序列的长度是多少。

    题解:

    很常见的一个3维CDQ。

    先按照z轴 sort 一遍,然后对于当前的序列去cdq分治。对于CDQ的每一层来说,都是用左边的点的值去更新右边点的值,对于每一层来说, 我们按照x轴sort, sort的时候注意,当同x的时候,一定是右边的询问点要在左边的修改点前面, 不然就不能保证前面的都是合法点, 对于每一个添加点来说,我们在其y轴对应的位置更新他的长度值, 对于每一个询问点来说, 我们在查询其y轴对应的位置的下面的地方去询问最长值。

    但是题目中要求的是严格递增序列。

    我们发现,会有中间的那一部分存在同z值的情况导致,中间偏左的点不能去更新中间偏右的点,但是我们可以发现,这个情况只会出现一个位置,对于每一次分治来说,那么我们开2个树状数组,去维护这个东西,一个梳妆数组存下左边的所有的更新点的值, 另一个梳妆数组维护 除去前面中间偏左不能维护中间偏右的那些点以外的值。

    代码:

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
      4 #define LL long long
      5 #define ULL unsigned LL
      6 #define fi first
      7 #define se second
      8 #define pb push_back
      9 #define lson l,m,rt<<1
     10 #define rson m+1,r,rt<<1|1
     11 #define lch(x) tr[x].son[0]
     12 #define rch(x) tr[x].son[1]
     13 #define max3(a,b,c) max(a,max(b,c))
     14 #define min3(a,b,c) min(a,min(b,c))
     15 typedef pair<int,int> pll;
     16 const int inf = 0x3f3f3f3f;
     17 const LL INF = 0x3f3f3f3f3f3f3f3f;
     18 const LL mod =  (int)1e9+7;
     19 const int N = 3e5 + 100;
     20 int ans[N];
     21 int a, b, C = ~(1<<31), M = (1<<16)-1;
     22 int r(){
     23     a = 36969 * (a & M) + (a >> 16);
     24     b = 18000 * (b & M) + (b >> 16);
     25     return (C&((a<<16)+b)) % 1000000;
     26 }
     27 struct Node{
     28     int id, x, y, z;
     29 }q[N], tmp[N];
     30 bool cmp1(Node & n1, Node & n2){
     31     return n1.z < n2.z;
     32 }
     33 bool cmp2(Node & n1, Node & n2){
     34     if(n1.x != n2.x) return n1.x < n2.x;
     35     return n1.id > n2.id;
     36 }
     37 int yyy[N];
     38 int tree[2][N];
     39 void Add(int x, int val, int op){
     40     for(int i = x; i < N; i+=i&(-i))
     41         tree[op][i] = max(tree[op][i], val);
     42     return ;
     43 }
     44 int query(int x, int op){
     45     int ret = 0;
     46     for(int i = x; i > 0; i -= i&(-i))
     47         ret = max(tree[op][i], ret);
     48     return ret;
     49 }
     50 void Clear(int x, int op){
     51     for(int i = x; i < N; i+=i&(-i))
     52         tree[op][i] = 0;
     53     return ;
     54 }
     55 void cdq(int l,int r){
     56     if(l == r) {
     57         ans[l] = max(ans[l], 1);
     58         return ;
     59     }
     60     int m = l+r >> 1;
     61     cdq(l, m);
     62     for(int i = l; i <= r; i++)
     63         tmp[i] = q[i];
     64     int midz = q[m+1].z;
     65     sort(tmp+l, tmp+r+1, cmp2);
     66     for(int i = l; i <= r; i++){
     67         if(tmp[i].id <= m){
     68             Add(tmp[i].y,ans[tmp[i].id],0);
     69             if(tmp[i].z != midz) Add(tmp[i].y,ans[tmp[i].id],1);
     70         }
     71         else{
     72             int val;
     73             if(tmp[i].z != midz) val = query(tmp[i].y-1, 0);
     74             else val = query(tmp[i].y-1,1);
     75             ans[tmp[i].id] = max(ans[tmp[i].id], val+1);
     76         }
     77     }
     78     for(int i = l; i <= r; i++){
     79         if(tmp[i].id <= m){
     80             Clear(tmp[i].y, 0);
     81             if(tmp[i].z != midz) Clear(tmp[i].y,1);
     82         }
     83     }
     84     cdq(m+1, r);
     85 }
     86 int main(){
     87     int m, n, A, B;
     88     while(~scanf("%d%d%d%d", &n, &m, &A, &B) && n+m+A+B){
     89         a = A, b = B;
     90         for(int i = 1; i <= n; i++){
     91             scanf("%d%d%d", &q[i].x, &q[i].y, &q[i].z);
     92             yyy[i] = q[i].y;
     93         }
     94         for(int i = n+1; i <= n+m; i++){
     95             q[i].x = r(); q[i].y = r(); q[i].z = r();
     96             yyy[i] = q[i].y;
     97         }
     98         sort(yyy+1, yyy+1+n+m);
     99         sort(q+1, q+1+n+m, cmp1);
    100         int ysz = unique(yyy+1,yyy+1+n+m) - yyy - 1;
    101         for(int i = 1; i <= n+m; i++){
    102             q[i].id = i;
    103             q[i].y = lower_bound(yyy+1,yyy+1+ysz,q[i].y) - yyy;
    104             ans[i] = 1;
    105         }
    106         cdq(1, n+m);
    107         int fans = 0;
    108         for(int i = 1; i <= n+m; i++)
    109             fans = max(fans, ans[i]);
    110         printf("%d
    ", fans);
    111     }
    112     return 0;
    113 }
    View Code
  • 相关阅读:
    关于oracle数据库(10)函数
    关于oracle数据库(9)
    关于oracle数据库(8)查询2
    关于oracle数据库(7)查询1
    关于oracle数据库(6)约束
    关于oracle数据库(5)增删改查
    关于oracle数据库(4)数据类型
    爬虫之beautifulsoup
    影视项目报错情况及处理
    多app应用等系列汇总
  • 原文地址:https://www.cnblogs.com/MingSD/p/9829651.html
Copyright © 2020-2023  润新知