博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
火柴排队(NOIP2013)(附树状数组专题讲解(其实只是粗略。。。))
阅读量:4482 次
发布时间:2019-06-08

本文共 1892 字,大约阅读时间需要 6 分钟。

首先,这道题目是一道神奇的题。

看到这道题,第一眼就觉得2个数组排个序,然后一一对应的时候一定差值最小。

由于我们可以将这2个数列同时进行调换。

所以我们先把2个数列排个序。

第二个序列中的数组的下标都指向第一个数组中的数的原来位置(其实就是离散化(真是啰嗦。。))

离散化之后,我们就变成了一个混乱的数列变成升序数列的操作次数是多少。

然后自然就会想到逆序对。每次变换之后逆序对的个数最多只能-1;

所以答案就是数列中逆序对的个数。

然后就是求逆序对啦。

逆序对有很多种做法:

TOP1:暴力O(N^2)时间TLE BOOM。。。!

TOP2:归并排序

TOP3:线段树

TOP4:树状数组(就是我写的)(又短又好写233~(PS:其实是其他的不会。。))

好吧。

其实我树状数组写的时候也不会,现学的。。

顺便讲讲树状数组的几个基本操作;

NUM1: update

代码如下:

void update(int x){    while(x<=n)    {        d[x]++;        x+=lowbit(x);        }    }

这就相当于给树状数组赋值/(+/-一个值)

在此lowbit就是x在二进制下的第一个1的位置。

实在看不懂可以找规律: 比如x=1时,n=8时,我们要赋值的数组为d[1],d[2],d[4],d[8];

当x=3时,我们要赋值的数组为d[3],d[4],d[8];

x=5:d[5],d[6],d[8];

恩,就是这样。

NUM2:getsum(相当于查询)

下面贴代码

int getsum(int x){    int ans=0;    while(x>0)    {        ans+=d[x];        x-=lowbit(x);        }    return ans;}

相当于上一个查询顺序反过来(好像语序有问题。。。)

然后呢,这题就用这2个函数来求逆序对的个数。

在本代码中getsum(x)求的是x之前<=x的数的数量。

这样i-getsum(x)就是x之前>x的数的数量

即对于x的逆序对个数

最后累加一下,就是答案啦!

注意!在本代码中,c数组用于离散化,防止爆栈,同时也加快效率。

d[i]表示在c[i-lowbit(i)]到c[i]中<=c[i]的数出现的总次数!(重点!这个点我理解了很久,要多多消化。也许是因为我蒟蒻。。。)

好吧,下面贴代码

#include
#include
#include
using namespace std;int c[100001];struct lisan{ int value,opt;}a[100001],b[100001];int cmp(lisan a,lisan b){
return a.value
0) { ans+=d[x]; x-=lowbit(x); } return ans;}int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&a[i].value); a[i].opt=i; } for(int i=1;i<=n;i++) { scanf("%d",&b[i].value); b[i].opt=i; } sort(a+1,a+n+1,cmp); sort(b+1,b+n+1,cmp); for(int i=1;i<=n;i++) c[b[i].opt]=a[i].opt; int ans=0; for(int i=1;i<=n;i++) { update(c[i]); ans+=i-getsum(c[i]); ans=ans%99999997; } printf("%d\n",ans);}

祝大家编程愉快啦233~(反正我理解了1个多小时。。)

然后狠狠的被CLZ,QRC等一群学弟和zxyerD了一顿。。

转载于:https://www.cnblogs.com/ghostfly233/p/6847508.html

你可能感兴趣的文章
Django系列(一)
查看>>
【ASP.NET Web API教程】2.3.3 创建Admin控制器
查看>>
第二类斯特林数
查看>>
Mysql
查看>>
JQuery中简约的进度条插件推荐
查看>>
url override and HttpSession implements session for form
查看>>
printf("\033[1;33m ***** \033[0m \n");
查看>>
在Winform开发框架中使用DevExpress的内置图标资源
查看>>
机器算法中的数据预处理
查看>>
selenium+python实现自动化登录
查看>>
从一列数中筛除尽可能少的数使得从左往右看,这些数是从小到大再从大到小的(网易)。...
查看>>
Python基础-文件操作
查看>>
Java ConcurrentModificationException异常原因和解决方法
查看>>
获取本机ip地址
查看>>
虚函数与纯虚函数的代码解读——2
查看>>
SQL Server 安装程序失败 不能在控件上调用 Invoke 或 BeginInvoke
查看>>
bzoj3283: 运算器
查看>>
jsp的标签
查看>>
HTML中的SVG
查看>>
HDU 5492 Find a path
查看>>