递增三元组(前缀和 二分)

1236. 递增三元组

题意描述:
在这里插入图片描述
在这里插入图片描述

解题核心:遍历B数组以寻找满足条件的A中和C中元素的个数;

解法一

前缀和: 由于A,B,C元素值较小,可做数组下标;

#include<iostream>
#include<cstdio>
#define LL long long
using namespace std;
const int N = 1e5+7;

int n,a[N],b[N],c[N],t;
int aa[N],cc[N];

int main()
{
	cin>>n;
	for(int i=0;i<n;i++) scanf("%d",&t),a[t]++;
	for(int i=0;i<n;i++) scanf("%d",&b[i]);
	for(int i=0;i<n;i++) scanf("%d",&t),c[t]++;
	
	aa[0]=a[0],cc[0]=c[0];
	for(int i=1;i<=1e5;i++){
		aa[i] = a[i] + aa[i-1] ;
		cc[i] = c[i] + cc[i-1] ;
	}
	LL ans = 0;
	for(int i=0;i<n;i++){
		ans += (LL)(aa[b[i]] - a[b[i]]) * (LL)(n - cc[b[i]]);
	}
	cout<<ans<<endl;
	return 0;
 } 

解法二

二分: 排序后使用二分函数

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<unordered_map>
#define LL long long 
using namespace std;
const int N = 1e5+7;

int n;
int a[N],b[N],c[N];

int main()
{
	cin>>n;
	for(int i=0;i<n;i++) scanf("%d",&a[i]);
	for(int i=0;i<n;i++) scanf("%d",&b[i]);
	for(int i=0;i<n;i++) scanf("%d",&c[i]);
	
	sort(a,a+n);
	sort(c,c+n);
	LL ans=0 ;
	for(int i=0;i<n;i++){
		LL aa=0,cc=0;
		if(b[i]>a[0]) aa = lower_bound(a,a+n,b[i])-a;
		else continue;
		if(b[i]<c[n-1]) cc = upper_bound(c,c+n,b[i])-c;
		else continue;
		ans+= aa*(n-cc);
	}
	cout<<ans<<endl;
	return 0;
}
发布了31 篇原创文章 · 获赞 2 · 访问量 1463

猜你喜欢

转载自blog.csdn.net/weixin_44851176/article/details/104189066
今日推荐