b_lq_递增三元组(排序+双指针 / 手写lower/upper_bound)

递增三元组

请你统计有多少个三元组 (i,j,k) 满足:

  • 1≤i,j,k≤N
    Ai<Bj<Ck

排序+双指针

思路
排序A、B、C,然后固定B的元素B[i],在A里找小于B[i]的数的个数 a、C里找大于B[i]的数的个数 b,对答案的贡献是:a*b

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
int n, a[N], b[N], c[N];
int main() {
    std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    cin>>n;
    for (int i=0; i<n; i++) cin>>a[i];
    for (int i=0; i<n; i++) cin>>b[i];
    for (int i=0; i<n; i++) cin>>c[i];
    sort(a,a+n), sort(b,b+n), sort(c,c+n);
    
    ll ans=0, j=0, k=0;
    for (int i=0; i<n; i++) {
        while (j<n && a[j]<b[i]) j++;
        while (k<n && b[i]>=c[k])k++;
        ans+=j*(n-k);
    }
    cout<<ans;
    return 0;
}

排序+lower/upper_bound

这是初始版本的代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
ll n,ans,a[N],b[N],c[N];
int lower_bound0(ll t[], ll x) { //第一个≥x
    int l=1, r=n+5; //数组下标从0开始
    while (l<r) {
       int m=l+r>>1;
       if (t[m]>=x) r=m; //≥的时候需要取到m,因为有可能m就是唯独一个≥x的了,所以要保证
       else l=m+1; //==x都不符合,那m这个位置就不可能>x
    }
    return l;
}
int upper_bound0(ll t[], ll x) { //第一个>x
    int l=1, r=n+1;
    while (l<r) {
        int m=l+r>>1;
        if (t[m]>x) r=m;
        else l=m+1; 
    }
    return l;
}
int main() {
    std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    cin>>n; 
    for (int i=1; i<=n; i++) cin>>a[i]; sort(a+1,a+n+1);
    for (int i=1; i<=n; i++) cin>>b[i]; 
    for (int i=1; i<=n; i++) cin>>c[i]; sort(c+1,c+n+1);
    for (int i=1; i<=n; i++) {
        ll j=lower_bound0(a, b[i])-1, k=n-upper_bound0(c, b[i])+1;
        ans+=j*k;
    }
    cout<<ans;
    return 0;
}

顺序三元组

给定n个元素,至于为[1,3]问有多少个元素能组成满足以下条件的三元组:

  • i<j<k,a[i]<a[j]<a[k]

思路:思维题一道,先统计出3的个数c3,顺序遍历一遍数组,遇到3,c3则减去1,这样可以保证遇到2时,c3都是2后面的3

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
ll n,a[N],ans,c1,c2,c3;
int main() {
    std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    cin>>n; for (int i=0; i<n; i++) cin>>a[i], c3+=a[i]==3;
    for (int i=0; i<n; i++) {
        if (a[i]==1) c1++;
        else if (a[i]==3) c3--;
        else ans+=c1*c3;
    }
    cout<<ans;
    return 0;
}
posted @ 2020-10-06 21:33  童年の波鞋  阅读(141)  评论(0编辑  收藏  举报