codeforces 252 C. Points on Line 枚举+思维
要求最远的不能超过d;
又因为保证了递增
那我们固定一个点,找到数列里第一个刚好<=该点+d的位置
然后区间中任意挑两个数都是合法的;
c(2,m)√
#
如何找到第一个刚好<=?
不手写二分的话用
ll r=upper_bound(a+1,a+n+1,tmp)-a; r--;
注意是upper,和lower的区别是它可以==,我们要的就是==;
注意-=1;
#
到后面会溢出,没开longlong见祖宗系列;
#include<bits/stdc++.h> using namespace std; typedef long long ll; ll a[100005]; int main( ) { ll n,d; ll ans=0; cin>>n>>d; for(ll i=1;i<=n;i++) { cin>>a[i]; } for(ll i=1;i<=n;i++) { ll tmp; tmp=a[i]+d; ll r=upper_bound(a+1,a+n+1,tmp)-a; r--; //cout<<r<<endl; if(r<=n&&r-i>=2&&a[r]-a[i]<=d) { ans+=(r-i)*(r-i-1)/2; //cout<<r<<" "<<i<<endl; } else if(r>n&&n-i>=2&&a[n]-a[i]<=d) { ans+=(n-i)*(n-i-1)/2; //cout<<r<<" "<<i<<endl; } } /* 31 0 36 0 43 1 47 1 48 0 50 0 56 0 */ //cout<<a[i]<<" "<<tmp<<" "<<r<<endl cout<<ans; }