zoukankan      html  css  js  c++  java
  • CodeForces12D 树状数组降维

    http://codeforces.com/problemset/problem/12/D

    题意

    给N (N<=500000)个点,每个点有x,y,z ( 0<= x,y,z <=10^9 )

    对于某点(x,y,z),若存在一点(x1,y1,z1)使得x1 > x && y1 > y && z1 > z 则点(x,y,z)是特殊点。

    问N个点中,有多少个特殊点。

    乍一看以为是裸的三位偏序问题,直接联想到了cdq分治,但是事实上这题和三位偏序有很大的差异,三位偏序问题求的是偏序的组数,但这题问的是完全被小于的个数,cdq分治上很难维护一个点是否已经被“超越”过,也不需要这么麻烦的去维护,事实上一维将x从大到小排序,一维作为树状数组上点的位置,越大的位置在越靠前,一维就是树状数组维护的前缀最大值即可。

    #include <map>
    #include <set>
    #include <ctime>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <string>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <sstream>
    #include <iostream>
    #include <algorithm>
    #include <functional>
    using namespace std;
    #define For(i, x, y) for(int i=x;i<=y;i++)  
    #define _For(i, x, y) for(int i=x;i>=y;i--)
    #define Mem(f, x) memset(f,x,sizeof(f))  
    #define Sca(x) scanf("%d", &x)
    #define Sca2(x,y) scanf("%d%d",&x,&y)
    #define Scl(x) scanf("%lld",&x);  
    #define Pri(x) printf("%d
    ", x)
    #define Prl(x) printf("%lld
    ",x);  
    #define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
    #define LL long long
    #define ULL unsigned long long  
    #define mp make_pair
    #define PII pair<int,int>
    #define PIL pair<int,long long>
    #define PLL pair<long long,long long>
    #define pb push_back
    #define fi first
    #define se second 
    typedef vector<int> VI;
    const double eps = 1e-9;
    const int maxn = 5e5 + 10;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9 + 7; 
    int N,M,tmp,K,cnt;
    int Hash[maxn]; 
    struct Node{
        int a,b,c;
    }node[maxn];
    bool cmp(Node a,Node b){
        return a.a > b.a;
    }
    int tree[maxn];
    void add(int x,int y){
        for(;x <= cnt;x += x & -x) tree[x] = max(tree[x],y);
    }
    int getmax(int x){
        int s = 0;
        for(;x > 0;x -= x & -x) s = max(s,tree[x]);
        return s;
    }
    int main()
    {
        Sca(N);
        For(i,1,N) scanf("%d",&node[i].a);
        For(i,1,N) scanf("%d",&node[i].b);
        For(i,1,N) scanf("%d",&node[i].c);
        For(i,1,N) Hash[i] = node[i].c;
        sort(Hash + 1,Hash + 1 + N);
        cnt = unique(Hash + 1,Hash + 1 + N) - Hash - 1;
        For(i,1,N) node[i].c = cnt + 1 - (lower_bound(Hash + 1,Hash + 1 + cnt,node[i].c) - Hash);
        sort(node + 1,node + 1 + N,cmp);
        int ans = 0;
        For(i,1,N){
            int j = i;
            while(j <= N && node[i].a == node[j].a) j++;j--;
            For(k,i,j){
                int t = getmax(node[k].c - 1);
                if(t > node[k].b) ans++;
            }
            For(k,i,j) add(node[k].c,node[k].b);
            i = j;
        }
        Pri(ans);
        #ifdef VSCode
        system("pause");
        #endif
        return 0;
    }
  • 相关阅读:
    Hadoop集群搭建
    计算机网络学习笔记——初探七层模型
    设计模式之——单例模式
    类的六种关系
    简述JMM
    GC四大算法
    堆和堆参数调优
    Redis持久化
    一次完整的http请求过程
    __add__,关于运算符重载(用户权限)
  • 原文地址:https://www.cnblogs.com/Hugh-Locke/p/9614848.html
Copyright © 2011-2022 走看看