• Codeforces 12D Ball(线段树)


    N ladies attend the ball in the King's palace. Every lady can be described with three values: beauty, intellect and richness. King's Master of Ceremonies knows that ladies are very special creatures. If some lady understands that there is other lady at the ball which is more beautiful, smarter and more rich, she can jump out of the window. He knows values of all ladies and wants to find out how many probable self-murderers will be on the ball. Lets denote beauty of the i-th lady by Bi, her intellect by Ii and her richness by Ri. Then i-th lady is a probable self-murderer if there is some j-th lady that Bi < Bj, Ii < Ij, Ri < Rj. Find the number of probable self-murderers.

    Input

    The first line contains one integer N (1 ≤ N ≤ 500000). The second line contains N integer numbers Bi, separated by single spaces. The third and the fourth lines contain sequences Ii and Ri in the same format. It is guaranteed that 0 ≤ Bi, Ii, Ri ≤ 109.

    Output

    Output the answer to the problem.

    Examples
    input
    3
    1 4 2
    4 3 2
    2 5 3
    output
    1

    题意:给你一组人,每个人有三个数值a,b,c,如果存在一个人x的三个值均大于另一个人y的三个值,y将自杀,求最终有多少个人自杀?

    思路:一开始以为是三维偏序……幸好并非如此.

    如果只有两维的话,自然好解决,将一维从大到小排序,二维扔进一颗线段树,每次比较线段树中的最大值与当前要扔进的值,因为先放入的一维必然大,若此时二维又比线段树中已有二维小,这个数必然产生贡献.

    那么如何拓展到三维呢?

    刚刚的线段树还没有发挥到极致,比如区间求最小值.

    看看数据emmmm500000

    当然是离散化喽!

    将第一个值离散化作为线段树中的插入的位置

    将第二维从大到小排序这样可以忽略第二维的影响

    因为逐个插入线段树的第二维一定是递减的

    然后线段树中插入值的位置为第一维离散后的值

    存储的数为第三维的值

    对于每个新插入的数只要保证他插入的位置后面有一个值比他大的就产生了贡献(因为后放入所以y已经小了,插入的位置后面的数说明x也小了,若z再小说明此人跳楼自杀)

    然后就好啦!

    代码如下:

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define lson root<<1
    #define rson root<<1|1
    #define maxn 500005
    
    int t[maxn<<2],h[maxn],m,n;
    struct node
    {
        int x,y,z;
    }tr[maxn];
    
    bool cmp(node a,node b)
    {
        return a.y>b.y;
    }
    
    void push_up(int root)
    {
        t[root]=max(t[lson],t[rson]);
    }
    
    void build(int l,int r,int root)
    {
        t[root]=0;
        if(l==r)
        {
            return ;
        }
        int mid=(l+r)>>1;
        build(l,mid,lson);
        build(mid+1,r,rson);
    }
    
    void update(int l,int r,int root,int p,int x)
    {
        if(l==r)
        {
            t[root]=max(t[root],x);
            return;    
        }
        int mid=(l+r)>>1;
        if(p<=mid)
        {
            update(l,mid,lson,p,x);
        }
        else
        {
            update(mid+1,r,rson,p,x);
        }
        push_up(root);
    }
    
    int query(int l,int r,int root,int li,int ri)
    {
        if(li<=l&&r<=ri)
        {
            return t[root];
        }
        int mid=(l+r)>>1;
        int val=0;
        if(li<=mid)
        {
            val=max(query(l,mid,lson,li,ri),val);
        }
        if(r>mid)
        {
            val=max(query(mid+1,r,rson,li,ri),val);
        }
        return val;
    }
    
    void init()
    {
        sort(h,h+m);
        m=unique(h,h+m)-h;
        build(1,m,1);
        for(int i=0;i<n;i++)
        {
            tr[i].x=lower_bound(h,h+m,tr[i].x)-h+1;
        }
        sort(tr,tr+m,cmp);
    }
    
    int main()
    {
        int ans,i,j,k;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
            scanf("%d",&tr[i].x);
            h[i]=tr[i].x;
        }
        for(int i=0;i<n;i++)
        {
            scanf("%d",&tr[i].y);
        }
        for(int i=0;i<n;i++)
        {
            scanf("%d",&tr[i].z);
        }
        m=n;
        ans=0;
        init();
        for(i=0;i<n;i=j)
        {
            j=i;
            while(j<n&&tr[j].y==tr[i].y)
            {
                if(query(1,m,1,tr[j].x+1,m)>tr[j].z)
                {
                    ans++;
                }   
                j++;
            }
            for(k=i;k<j;k++)
            {
                update(1,m,1,tr[k].x,tr[k].z);
            }   
        }
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    Java Synchronized的用法
    静态方法中不能new内部类的实体对象
    android ViewGroup事件分发机制
    安卓设备通过USB接口读取UVC摄像头权限问题
    android View事件分发机制结论
    函数指针与指针函数以及typedef
    GeoHash
    快速排序,C语言实现
    字符串的几个算法
    ANSI C与GNU C
  • 原文地址:https://www.cnblogs.com/stxy-ferryman/p/8214235.html
Copyright © 2020-2023  润新知