CF-12D - Ball(排序+MAP)

D - Ball

Time Limit:3000MS   Memory Limit:262144KB   64bit IO Format:%I64d & %I64u

Description

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 thei-th lady by Bi, her intellect byIi and her richness byRi. Theni-th lady is a probable self-murderer if there is somej-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 containsN integer numbersBi, separated by single spaces. The third and the fourth lines contain sequencesIi andRi in the same format. It is guaranteed that0 ≤ Bi, Ii, Ri ≤ 109.

Output

Output the answer to the problem.

Sample Input

Input
3
1 4 2
4 3 2
2 5 3
Output
1

思路:l[i]代表第i个人的信息。把l按三个关键字排序,假设三个关键字分别为x,y,z。x,z从小到大,y从大到小。

因为已经先按x从小到大排了。   y从尾开始执行插入操作。    

所以每次只需往集合里找到第一个y大于要插入的值比较z看看要插入的是否自杀,若会,则自杀人数加1.并不做插入操作。

若不会自杀,则插入。并且去掉y,z都比l[i]小的集合中不会自杀的人
        因为接下来会因这些人而自杀的人肯定会因为l[i]而自杀

y执行到0结果也就出来了。

 

代码有注释,好理解。

#include<iostream>
#include<algorithm>
#include<map>
using namespace std;
const int mm=501000;
const int oo=1e9+2;
class node
{
public:
  int x,y,z;
}l[mm];
int n;
bool cmp(node a,node b)///x从小到大,y从大到小,z小到大
{
  return a.x!=b.x? a.x<b.x:a.y!=b.y?a.y>b.y:a.z<b.z;
}
map<int,int>mp;
map<int,int >::iterator it;
int main()
{
  while(cin>>n)
  {
    for(int i=0;i<n;i++)cin>>l[i].x;
    for(int i=0;i<n;i++)cin>>l[i].y;
    for(int i=0;i<n;i++)cin>>l[i].z;
    sort(l,l+n,cmp);

    mp[-oo]=oo;mp[oo]=-oo;///标记左右边界
    //cout<<mp[-oo]<<" "<<mp[oo];
    int ans=0;
    ///x是从小到大排
    for(int i=n-1;i>=0;i--)
    {
      it=mp.upper_bound(l[i].y);///找到比l[i].y大的第一个数
      if(it->second>l[i].z)ans++;///找到让l[i]自杀的人了
      else if(mp[l[i].y]<l[i].z)
      {
        mp[l[i].y]=l[i].z;///更新值,插入不会自杀的人
        ///去掉y,z都比l[i]小的集合中不会自杀的人
        ///因为接下来会因这些人而自杀的人肯定会因为l[i]而自杀
        for(it=--mp.lower_bound(l[i].y);it->second<l[i].z;)
          mp.erase(it--);
      }
    }
    cout<<ans<<"\n";
  }
}


 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值