[GZOI2017]配對統計

題目鏈接:[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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章