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;
    }
  • 相关阅读:
    POJ 1887 Testing the CATCHER
    HDU 3374 String Problem
    HDU 2609 How many
    POJ 1509 Glass Beads
    POJ 1458 Common Subsequence
    POJ 1159 Palindrome
    POJ 1056 IMMEDIATE DECODABILITY
    POJ 3080 Blue Jeans
    POJ 1200 Crazy Search
    软件体系结构的艺术阅读笔记1
  • 原文地址:https://www.cnblogs.com/Hugh-Locke/p/9614848.html
Copyright © 2011-2022 走看看