P5677 [GZOI2017]配对统计(树状数组)

本文介绍了一种解决区间内配对数量问题的算法。通过排序原数组并找到差值绝对值最小的配对,使用树状数组进行区间查询,最终得出指定区间内的配对总数。代码实现详细展示了算法步骤。
部署运行你感兴趣的模型镜像

题目链接

题意:

成为一个配对需要的条件是两个数在数组中的差值的绝对值最小,给你一个区间,求区间内一共有多少对配对。

思路:

首先排序处理原数组,然后在相邻位置找配对,再将找好的配对排序,将位置信息保留,放入树状数组中,查询区间内有多少配对的位置在查询范围内即可。

代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
const int N=1e6+7;
const int mod=1e9+7;
const int inf=0x7fffffff;
const double pi=3.1415926535;
int n,m,tot;
int tree[N],ans[N];
struct shuzu
{
    int num,place;
}sz[N];
struct ask
{
    int l,r,place;
}a[N];
struct peidui
{
    int l,r;
}pd[N];
bool cmp1(shuzu x,shuzu y)
{
    return x.num<y.num;
}
bool cmp2(ask x,ask y)
{
    return x.l<y.l;
}
bool cmp3(peidui x,peidui y)
{
    return x.l<y.l;
}
int lowbit(int x)
{
    return x&-x;
}
void add(int x,int y)
{
	while(x<=tot)
    {
		tree[x]+=y;
		x+=lowbit(x);
	}
}
int get(int x)
{
	int tmp=0;
	while(x)
    {
		tmp+=tree[x];
		x-=lowbit(x);
	}
	return tmp;
}
signed main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>sz[i].num;
		sz[i].place=i;
	}
	sort(sz+1,sz+n+1,cmp1);
	sz[0].num=sz[n+1].num=1<<30;
	for(int i=1;i<=n;i++)
    {
		if(abs(sz[i].num-sz[i-1].num)==abs(sz[i].num-sz[i+1].num))
		{
			pd[++tot].l=min(sz[i].place,sz[i-1].place);
			pd[tot].r=max(sz[i].place,sz[i-1].place);
			pd[++tot].l=min(sz[i].place,sz[i+1].place);
			pd[tot].r=max(sz[i].place,sz[i+1].place);
		}
		if(abs(sz[i].num-sz[i-1].num)<abs(sz[i].num-sz[i+1].num))
		{
			pd[++tot].l=min(sz[i].place,sz[i-1].place);
			pd[tot].r=max(sz[i].place,sz[i-1].place);
		}
		if(abs(sz[i].num-sz[i-1].num)>abs(sz[i].num-sz[i+1].num))
		{
			pd[++tot].l=min(sz[i].place,sz[i+1].place);
			pd[tot].r=max(sz[i].place,sz[i+1].place);
		}
	}
	sort(pd+1,pd+tot+1,cmp3);
	for(int i=1;i<=m;i++)
	{
		cin>>a[i].l>>a[i].r;
		a[i].place=i;
	}
	sort(a+1,a+m+1,cmp2);
	int tmp=tot;
	for(int i=m;i>=1;i--)
	{
		while(pd[tmp].l>=a[i].l)
		{
			add(pd[tmp].r,1);
			tmp--;
		}
		ans[a[i].place]=get(a[i].r);
	}
	int last=0;
	for(int i=1;i<=m;i++)
	{
	    last+=ans[i]*i;
	}
	cout<<last<<endl;
	return 0;
}

您可能感兴趣的与本文相关的镜像

ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值