題目鏈接:[GZOI2017]配對統計
其實我們把絕對值當成座標軸的距離,就可以發現其實就是最近點對的個數。
然後排序之後,每個找最近的對。
然後離線求解。
AC代碼:
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=3e5+10;
int n,m,res[N],d[N]; long long ans;
struct node{int id,a;}t[N];
struct qry{int id,l,r;}q[N];
vector<int> v[N];
int cmp1(node a,node b){return a.a<b.a;}
int cmp2(qry a,qry b){return a.r<b.r;}
inline void insert(int x){for(;x<=n;x+=x&(-x)) d[x]++;}
inline int ask(int x){int s=0; for(;x;x-=x&(-x)) s+=d[x]; return s;}
inline int ask(int l,int r){return ask(r)-ask(l-1);}
signed main(){
cin>>n>>m;
for(int i=1;i<=n;i++) scanf("%d",&t[i].a),t[i].id=i;
sort(t+1,t+1+n,cmp1);
for(int i=2;i<n;i++){
if(t[i].a*2==t[i-1].a+t[i+1].a){
v[max(t[i-1].id,t[i].id)].push_back(min(t[i-1].id,t[i].id));
v[max(t[i+1].id,t[i].id)].push_back(min(t[i+1].id,t[i].id));
}else{
if(t[i].a-t[i-1].a<t[i+1].a-t[i].a)
v[max(t[i-1].id,t[i].id)].push_back(min(t[i-1].id,t[i].id));
else
v[max(t[i+1].id,t[i].id)].push_back(min(t[i+1].id,t[i].id));
}
}
v[max(t[1].id,t[2].id)].push_back(min(t[1].id,t[2].id));
v[max(t[n].id,t[n-1].id)].push_back(min(t[n].id,t[n-1].id));
for(int i=1;i<=m;i++) scanf("%d %d",&q[i].l,&q[i].r),q[i].id=i;
sort(q+1,q+1+m,cmp2); int ed=1;
for(int i=1;i<=m;i++){
while(ed<=q[i].r){
for(auto j:v[ed]) insert(j); ed++;
}
res[q[i].id]=ask(q[i].l,q[i].r);
}
for(int i=1;i<=m;i++) ans+=1LL*res[i]*i;
cout<<ans;
return 0;
}