[Acwing | 蓝桥杯] 1236. 递增三元组 二分

前言

开学,练习开始了ohh
传送门 :

题意

给定三个三元组,求满足 A [ i ] < B [ j ] < C [ k ] A[i]<B[j]<C[k] A[i]<B[j]<C[k] 的组合数量

思路

朴素做法显然是三层循环直接枚举的, 1 e 5 ∗ 1 e 5 ∗ 1 e 5 1e5*1e5*1e5 1e5∗1e5∗1e5
但是我们发现我们可以通过 枚举 b b b数组, 然后二分寻找 a [ ] , b [ ] a[],b[] a[],b[]数组中满足条件的个数
然后通过乘法原理直接相乘即可优化 n ∗ l o g n*log n∗log

这个题目应该也可以使用树状数组作,暂做保留

CODE

#include <iostream>
#include <vector>
#include <map>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
#define IOS  ios::sync_with_stdio(false);
#define CIT  cin.tie(0);
#define COT  cout.tie(0);

#define ll long long
#define x first
#define y second
#define pb push_back
#define endl '\n'
#define all(x) (x).begin(),x.end()


typedef priority_queue<int,vector<int>,greater<int>>  Pri_m;
typedef pair<int,int> pii;
typedef vector<int> VI;
map<int,int> mp;

const int N  = 1e5+10;
int a[N],b[N],c[N];
int n;

void solve()
{
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	for(int i=1;i<=n;i++) cin>>b[i];
	for(int i=1;i<=n;i++) cin>>c[i];
	
	sort(a+1,a+1+n);
	sort(b+1,b+1+n);
	sort(c+1,c+1+n);
	
	ll ans = 0 ;
	//如果遍历 b数组的话 那么就是要找 a[]比他最小的最大的那个数
	//c[]是找比他最大的最小的那个数
	
	for(int i = 1;i<=n;i++){
		
		int cl = 0  ;
		
		int l = 1 , r = n;
		
		while(l<r){
			int mid = l+r+1>>1;
			if(a[mid] < b[i]) l = mid;
			else  r = mid-1;
			
		}
		
		if(a[l] >= b[i]) continue;
		cl = l ;
		
		
		l = 1, r = n;
		
		while(l<r){
			int mid = l+r>>1;
			if(c[mid] > b[i]) r = mid;
			else l = mid+1;
		}

		if(c[l] <= b[i]) continue;
		
		ans+= cl*(n-l+1)*1ll;
	}
	cout<<ans<<endl;
	
}

/**mYHeart is my algorithm**/
int main()
{
    //int t;cin>>t;while(t -- )
    solve();
    return 0;
}
上一篇:AFNetworking 提示"The resource could not be loaded because the App Transport Security policy requires the use of a secure connection" 解决办法


下一篇:SQL Server 2005 sa登录失败。已成功与服务器建立连接 但是在登录过程中发生错误。 provider 共享内存提供程序 error 0 管道的另一端上无任何进程。