二分模板题

题目传送门

主要思路:

  • 暴力会tle n的3次方了
  • 然后 二分可以找中间然后去二分枚举两边
    最后结果 ans+=a小于它的数*c大于它的数 注意要判断是否符合条件 即如果a的小于它的数还大于它就不成立 或者c的数小于它也不成立
  • 结果 要注意转long long ans+=(long long)tp1*tp2; int->longlong
#include
using namespace std;
int n;
int a[100009],b[100009],c[100009];
//找到第一个大于该数字的数
int get_max(int *num,int x){
   int l=1;int r=n; int mid=0;
   while(l<r){
       mid=(l+r)/2;
       if(num[mid]>x) r=mid;
       else l=mid+1;
   }
   return l;
}
// 得到第一个小于它的数
int get_min(int *num,int x)
{
   int l=1;
   int r=n; 
   int mid=0;
   while(l<r){
       mid=(l+r+1)/2;
       if(num[mid]<x) l=mid;
       else r=mid-1;
   }
   return l;
}
int main(){
       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(c+1,c+1+n);
     long long ans=0;
       for(int i=1;i<=n;i++){
           // cout<
           // cout<
           // if(b[i]<=a[1]||b[i]>=c[n]) continue;
           int tp1=n-get_max(c,b[i])+1;
           int tp2=get_min(a,b[i]);
           if(c[get_max(c,b[i])]<=b[i]||a[get_min(a,b[i])]>=b[i]) continue;
           ans+=(long long)tp1*tp2;
       }
       cout<<ans<<endl;
       return 0;
}
// #include 
// #include 
// #include 
// using namespace std;

// typedef long long LL;
// const int N = 1e5+10;
// int num[3][N];

// int main() {
//     int n;
//     scanf("%d", &n);
//     for(int i = 0; i < 3; ++i) 
//         for(int j = 1; j <= n; ++j) 
//             scanf("%d", &num[i][j]);
//     // for(int i = 0; i < 3; ++i)
//         sort(num[0]+1, num[0]+n+1);
//         sort(num[2]+1, num[2]+n+1);
//     LL ans = 0;
//     //枚举B,寻找A满足的个数以及C满足的个数相乘
//     for(int i = 1; i <= n; ++i) {
//         int key = num[1][i];
//         //A中二分查找第一个小于key的数的下标
//         int pos1 = lower_bound(num[0]+1, num[0]+n+1, key)-num[0]-1;
//         //C中二分查找第一个大于key的数的下标
//         int pos2 = upper_bound(num[2]+1, num[2]+n+1, key)-num[2];
//         if(pos1 >= 1 && pos2 <= n) {
//             ans += (LL)pos1*(n-pos2+1);
//         }
//     }
//     cout<
//     return 0;
// }


你可能感兴趣的:(算法模板,算法)