luogu CF12D Ball |樹狀數組

题意翻译

有N个女士去参加舞会。每个女士有三个值a[i],b[i],c[i]。如果一位女士发现有其它女士的这三个值都比自己高的话就会去跳楼.求有多少跳楼的女士。

读入:第一行为\(N\),第二行为每个人的\(B_i\)​值,第三行为每个人的\(I_i\)​值,第四行为每个人的\(R_i\)​值。 输出:一个整数,代表问题的答案

数据范围: 1 ≤ N ≤ 500000 0<=a[i],b[i],c[i]<=10^9


其實不用三位偏尋

把其中一個當下標,再用其中一個排序

就可以一口氣查兩個量的大小關系

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int mod=998244353,N=5e5+10;
#define int long long
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 n;
struct node{
	int w,a,b,c;
}e[N];
inline bool cmp1(node t1,node t2){
	return t1.w<t2.w;
}
inline bool cmp2(node t1,node t2){
	return t1.b>t2.b;
}
int c[N];

inline void add(int x,int y){
	for(;x;x-=x&(-x))c[x]=max(y,c[x]);
}

inline int getmax(int x){
	int res=0;
	for(;x<=n;x+=x&(-x))res=max(res,c[x]);
	return res;
}

signed main(){
	n=read();
	for(int i=1;i<=n;i++)e[i].w=read();
	for(int i=1;i<=n;i++)e[i].b=read();
	for(int i=1;i<=n;i++)e[i].c=read();
	sort(e+1,e+1+n,cmp1);
	int cnt=0;
	for(int i=1;i<=n;i++)
	if(e[i].w==e[i-1].w)e[i].a=cnt;
	else e[i].a=++cnt;
	
	sort(e+1,e+1+n,cmp2);
	int ans=0,j;
	for(int i=1;i<=n;){
		for(j=i;j<=n&&e[i].b==e[j].b;j++)
		if(getmax(e[j].a+1)>e[j].c)ans++;
		for(j=i;j<=n&&e[i].b==e[j].b;j++)
		add(e[j].a,e[j].c);
		i=j;
	}
	cout<<ans<<endl;
}

猜你喜欢

转载自www.cnblogs.com/naruto-mzx/p/12690336.html