CF12D Ball
用树状数组也能写
Idea
对于女人\(i\),想要知道她自不自杀,无非是有没有女人\(j\),使得\(B_i<B_j\&\&I_i<I_j\&\&R_i<R_j\)。这里用树状数组表示前\(i\)个女人中\(R\)值的最大值写,由于那三个值小于等于\(1e9\),所以必须离散化。相对其中某个量(这里我按\(B\)来排序)升序排序,然后编号,这样生成的树状数组,保证在查询时满足\(getmax(id+1)\)中所有的女人的\(B\)值比当前女人的要大。于是再按\(I\)值降序,这样保证在之后的遍历中,\(lady[i].i\ge lady[i-1].i\),再以\(R\)值更新树状数组
Code
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<string>
#define ll long long
#define maxn 500050
#define inf 2147483647
#define mod 10003
#define eps 1e-6
#define pi acos(-1.0)
#define de(x) ((x)*(x))
using namespace std;
inline int read(){
int x=0,f=1; char ch=getchar();
while(!isdigit(ch)) {if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)) {x=x*10+ch-48;ch=getchar();}
return x*f;
}
int c[maxn],cnt,n,ans;
struct Node{
int b,i,r,id;
}a[maxn];
inline void add(int x,int d){
while(x>0){
if(c[x]<d) c[x]=d;
x-=x&(-x);
}
}
inline int getmax(int x){
int res=-1;
for(int i=x;i<=cnt;i+=i&(-i))
if(res<c[i]) res=c[i];
return res;
}
inline bool cmp(Node a,Node b){return a.b<b.b;}
inline bool cmp1(Node a,Node b){return a.i>b.i;}
signed main(){
n=read();
int i,j;
for(i=0;i<n;i++) a[i].b=read();
for(i=0;i<n;i++) a[i].i=read();
for(i=0;i<n;i++) a[i].r=read();
sort(a,a+n,cmp); cnt=1; a[0].id=1;
for(i=1;i<n;i++)
if(a[i].b==a[i-1].b) a[i].id=cnt;
else a[i].id=++cnt;//这个地方不能写成cnt++;原因您们懂得
sort(a,a+n,cmp1);
for(i=1;i<=cnt;i++) c[i]=-1;
for(i=0;i<n;){
for(j=i;j<n&&a[i].i==a[j].i;j++)
if(getmax(a[j].id+1)>a[j].r) ans++;
for(j=i;j<n&&a[i].i==a[j].i;j++)
add(a[j].id,a[j].r);
i=j;
}
printf("%d",ans);
return 0;
}
不随波,追随梦;不逐流,攀耸峰。不卑,补我所失;不亢,胜我所向。