Luogu P1102 AB number pair (two points, map, double pointer)

Simple AB

Description
This is a simple question. Given a string of numbers and a number C, it is required to calculate the number of all A - B = C pairs (pairs with the same number in different positions are counted as different pairs).
Input
The input consists of two lines.
In the first line, two integers N, C. 1=<N<=2e5 , C>=1
In the second line, N integers are used as the string of numbers to be processed.

Output
one line, indicating the number of pairs that satisfy A - B = C contained in the string.

Input sample 1
4 1
1 1 2 3
Output sample 1
3

Input sample 2
6 1
1 1 1 2 2 2
Output sample 2
9

It is worth noting in this question that it is possible to violently int
such as

输入
200000 1
1e51,1e52
输出
1e10 > int(int存最大的数约等于2e9)

two points


Sort the simple dichotomous template questions first, find out the coordinates of the leftmost end point and the rightmost end point of C that are greater than the i-th number, (the right end point coordinate minus the left end point coordinate plus 1) indicates how many are more than the i- th Number of large C
such as sample 2
insert image description here

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int const N=2e5+10;
int n,c,a[N];
ll res;
int main()
{
    
    
    ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    //节约cin,cout时间;
    cin>>n>>c;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    sort(a+1,a+1+n);
    for(int i=1;i<=n;i++)
    {
    
    
        int l=i+1,r=n;
        while(l<r)  //找最左端点;r=mid;
      {
    
    
        int mid=l+r >>1;
         //相当于(l+r)/2,这么写看着厉害一点hh,+优先级大于>>(右移)优先级;
        if(a[mid]-a[i]>=c)
            r=mid;
        else
            l=mid+1;
      }
      int k=l;
      l=i+1,r=n;
      while(l<r)//找最右端点;l=mid;
      {
    
    
          int mid=l+r+1 >> 1;//改l,要+1,防止死循环
          if(a[mid]-a[i]<=c)
            l=mid;
          else
            r=mid-1;
      }
      int kk=l;
      if(a[kk]-a[i]==c&&a[k]-a[i]==c)
        res+=kk-k+1;
    }
    cout<<res<<endl;
    return 0;
}

lower_bound()
upper_bound()

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int const N=2e5+10;
int n,c,a[N],b[N];
ll res;
int main()
{
    
    
    ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    //节约cin,cout时间;
    cin>>n>>c;
    for(int i=1;i<=n;i++)
    {
    
    
        cin>>a[i];
        b[i]=a[i]+c;//用b[N]数组存(对应的)的大C的值
    }
    sort(a+1,a+1+n);
    for(int i=1;i<=n;i++)
    {
    
    
       int k=lower_bound(a+1,a+n+1,b[i])-a;//返回第一个大于等于b[i]的a数组的下标
       int kk=upper_bound(a+1,a+n+1,b[i])-a;//返回大于
       res+=kk-k;//因为upper_bound返回大于的下标,所以无需加1

    }
    cout<<res<<endl;
    return 0;
}

double pointer

The specific implementation is that we maintain two endpoints kk , k, each time kk moves right to the a[kk] - a[i] <= cnext position of the last position, and k moves right to meet a[k] - a[l] < cthe last position.
That is to say, if at this time a[kk] - a[i] == c && a[k] - a[i] == c, the middle segment must be All the conditions are met, we just let res += kk - kit go.

#include <bits/stdc++.h>
using namespace std;
int const N=200010;
typedef long long ll;
int a[N],n,c;
ll res;
int main()
{
    
    
    ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
     //节约cin,cout时间;
    cin>>n>>c;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    sort(a+1,a+1+n);
    int kk=2,k=2;
    for(int i=1;i<=n;i++)
    {
    
    
       while(kk<=n&&a[kk]-a[i]<=c)
        kk++; //因为是有序的,下次寻找从kk开始;减少不必要的枚举
       while(k<=n&&a[k]-a[i]<c)
        k++;
       if(a[kk-1]-a[i]==c&&a[k]-a[i]==c)
        res+=kk-k;
    }
    cout<<res<<endl;
    return 0;
}

MAP time complexity O(n)

Summary of map usage

#include<iostream>
#include<cstring>
#include<algorithm>
#include<map>     //map头文件;
using namespace std;
typedef long long ll;
int const N=2e5+10;
int n,c,a[N],b[N];
ll res;
map<int,int> mp;//key-value;建立一个数字到出现次数的映射 map<a[i],times>
int main()
{
    
    
    ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    //节约cin,cout时间;
    cin>>n>>c;
    for(int i=1;i<=n;i++)
    {
    
    
        cin>>a[i];
        mp[a[i]]++;
    }
    sort(a+1,a+1+n);
    for(int i=1;i<=n;i++)
    {
    
    
      res+=mp[a[i]+c];
    }
    cout<<res<<endl;
    return 0;
}

Guess you like

Origin blog.csdn.net/weixin_52879528/article/details/123115091