http://codeforces.com/problemset/problem/12/D
//这三维 一维是插入顺序 一维是插入位置 一维是插入的值
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define LL(x) (x<<1)
#define RR(x) ((x<<1)|1)
const int maxn=500050;
struct node{
int b,i,r;
}p[maxn];
int num[maxn];
int tot;
int Bin(int x)
{
int l=0,r=tot,mid;
while(l<=r)
{
mid=(l+r)>>1;
if(num[mid]<x)
l=mid+1;
else if(num[mid]>x)
r=mid-1;
else
return mid;
}
return -1;
}
int cmp(node x,node y)
{
if(x.b!=y.b) return x.b<y.b;
if(x.i!=y.i) return x.i<y.i;
return x.r<y.r;
}
struct Seg{
int l,r;
int max;
}tree[maxn*3];
void build(int l,int r,int k)
{
tree[k].l=l;
tree[k].r=r;
tree[k].max=-1;
if(l==r) return ;
int mid=(l+r)>>1;
build(l,mid,LL(k));
build(mid+1,r,RR(k));
}
int Max(int a,int b){
if(a>b) return a;
return b;
}
void update(int l,int k,int val)
{
if(l==tree[k].l && l==tree[k].r)
{
tree[k].max=Max(tree[k].max,val);
return ;
}
int mid=(tree[k].l+tree[k].r)>>1;
if(l<=mid) update(l,LL(k),val);
else update(l,RR(k),val);
tree[k].max=Max(tree[LL(k)].max,tree[RR(k)].max);
}
int query(int l,int r,int k)
{
if(l>r) return -1;
if(l<=tree[k].l && tree[k].r<=r)
return tree[k].max;
int mid=(tree[k].l+tree[k].r)>>1;
if(r<=mid) return query(l,r,LL(k));
else if(l>mid) return query(l,r,RR(k));
else return Max(query(l,r,LL(k)),query(l,r,RR(k)));
}
int main()
{
int n;
int i,j;
while(scanf("%d",&n)!=EOF)
{
tot=0;
for(i=0;i<n;i++)
scanf("%d",&p[i].b);
for(i=0;i<n;i++)
{
scanf("%d",&p[i].i);
num[tot++]=p[i].i;
}
for(i=0;i<n;i++)
scanf("%d",&p[i].r);
sort(num,num+tot);
for(i=1,j=0;i<tot;i++)
if(num[j]!=num[i])
num[++j]=num[i];
tot=j;
for(i=0;i<n;i++)
p[i].i=Bin(p[i].i);
sort(p,p+n,cmp);
int ans=0;
build(0,tot,1);
// for(i=0;i<n;i++)
// {
// printf("%d %d %d\n",p[i].b,p[i].i,p[i].r);
// }
for(i=n-1,j=n-1;i>=0;i--)
{
while(p[j].b!=p[i].b && j>=0)
{
update(p[j].i,1,p[j].r);
j--;
}
if(p[i].r<query(p[i].i+1,tot,1))
{
// printf("i==%d\n",i);
ans++;
}
}
printf("%d\n",ans);
}
return 0;
}
(not mine)
//树状数组 其实就是二叉树的性质求 (x+1->tot tot定值)
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 500010;
int c[N];
int num[N];
int n;
struct node{
int x,y,z;
}in[N];
inline int Max(int &a,int b){
if(a<b) return b;
return a;
}
void update(int x,int d){
for(;x<N;x+=x&-x) c[x]=Max(c[x],d);
}
int sum(int x){
int ans=0;
for(;x>0;x-=x&-x) ans=Max(ans,c[x]);
return ans;
}
void init(){
sort(num+1,num+n+1);
int tot=unique(num+1,num+n+1)-num-1;
for(int i=1;i<=n;i++)
in[i].x=tot-(lower_bound(num+1,num+1+tot,in[i].x)-num-1);
}
inline int cmp(node a,node b){
return a.y>b.y;
}
int main()
{
int i,j,k;
scanf("%d",&n);
for(i=1;i<=n;i++) {scanf("%d",&in[i].x); num[i]=in[i].x;}
for(i=1;i<=n;i++) scanf("%d",&in[i].y);
for(i=1;i<=n;i++) scanf("%d",&in[i].z);
init();
memset(c,0,sizeof(c));
sort(in+1,in+n+1,cmp);
int ans=0;
for(i=1;i<=n;i=j){
for(j=i;j<=n&&in[j].y==in[i].y;j++){
int z=sum(in[j].x-1);
if(z>in[j].z) ans++;
}
for(;i<=j-1;i++)
update(in[i].x,in[i].z);
}
printf("%d\n",ans);
return 0;
}