【以前的空间】BIT的两个小小运用
剩下一点点时间,就来说说最近才会的关于bit的两个妙用。
求一组数的逆序对
求最长不下降序列
其实两个东西思想差不多,就已第一个为例讲讲。
就是所有数排一遍后,再按照原序列顺序(从后往前),做如下操作:
1、1-(这个数排名-1)的区间和,结果加到答案中
2、把这个数排名为+1
操作1、2分别对应区间查询和单点修改,于是就是bit维护。
为什么这样就是答案呢?
因为如果有比这个数更小的,且在这个数之后,那么在这个更小的数在之前就已经加入到bit中,也就是排名小于当前数的数且都在bit中的数(也就意味着在这个数之后且小于这个数),便与这个数成逆序对。
最长不下降序列也差不多,只是询问的是区间最值罢了。
最后注意数值重复的情况!!!
var
i,j,k,l,n,ans,tot:longint;
a,b,c,tree:array[..]of longint; procedure swap(var x,y:longint);
var
i:longint;
begin
i:=x;
x:=y;
y:=i;
end; procedure qsort(l,r:longint);
var
i,j,k,mid:longint;
begin
i:=l;
j:=r;
mid:=a[(l+r)>>];
repeat
while a[i]>mid do inc(i);
while a[j]<mid do dec(j);
if i<=j then begin
swap(a[i],a[j]);
swap(b[i],b[j]);
inc(i);
dec(j);
end;
until i>j;
if l<j then qsort(l,j);
if i<r then qsort(i,r);
end; function lowbit(x:longint):longint;
begin
exit(x and (-x));
end; function ask(x:longint):longint;
var
sum:longint;
begin
sum:=;
while x> do begin
inc(sum,tree[x]);
dec(x,lowbit(x));
end;
exit(sum);
end; procedure add(x:longint);
begin
while x<=n do begin
inc(tree[x]);
inc(x,lowbit(x));
end;
end; begin
readln(n);
for i:= to n do begin
read(a[i]);
b[i]:=i;
end;
qsort(,n);
tot:=;
for i:=n downto do begin
if a[i]<>a[i+] then inc(tot);
c[b[i]]:=tot;
end;
for i:=n downto do begin
ans:=ans+ask(c[i]-);
add(c[i]);
writeln(ans);
end;
end. var
a,b,c,tree,f:array[..]of longint;
i,j,k,l,n,m,tot:longint; procedure swap(var x,y:longint);
var
i:longint;
begin
i:=x;
x:=y;
y:=i;
end; function max(x,y:longint):longint;
begin
if x>y then exit(x);
exit(y);
end; procedure qsort(l,r:longint);
var
i,j,k,mid:longint;
begin
i:=l;
j:=r;
mid:=a[(l+r)>>];
repeat
while a[i]>mid do inc(i);
while a[j]<mid do dec(j);
if i<=j then begin
swap(a[i],a[j]);
swap(b[i],b[j]);
inc(i);
dec(j);
end;
until i>j;
if l<j then qsort(l,j);
if i<r then qsort(i,r);
end; function lowbit(x:longint):longint;
begin
exit(x and (-x));
end; function ask(x:longint):longint;
var
sum:longint;
begin
sum:=;
while x> do begin
sum:=max(sum,tree[x]);
dec(x,lowbit(x));
end;
exit(sum);
end; procedure add(x,y:longint);
begin
while x<=n do begin
tree[x]:=max(tree[x],y);
inc(x,lowbit(x));
end;
end; begin
readln(n);
for i:= to n do begin
read(a[i]);
b[i]:=i;
end;
qsort(,n);
tot:=;
k:=;
for i:= to n do begin
if a[i]<>a[i-] then inc(tot);
c[b[i]]:=tot;
end;
for i:=n downto do begin
f[i]:=ask(c[i]-)+;
add(c[i],f[i]);
if f[i]>k then k:=f[i];
end;
writeln(k);
end.
【以前的空间】BIT的两个小小运用的更多相关文章
- linux系统的磁盘空间限制的两种方法
最近在搞VPS,要用到磁盘的限额,在网上找了一些相关的资料,总结起来,有两个方法能实现,一是用quota,另外一种是限制目录大小,下面我就将这两种方法写出来,与大家一起分享! 首先我们来看第一种方法, ...
- 剑指offer-第五章优化时间和空间效率(两个链表的第一个公共节点)
思路1:要求的是两个链表的第一个公共节点,首先想到的是用栈来存放两个链表,然后依次从栈中抛出,直到最后一个相同的节点为止.但是要用到两个栈,空间复杂度为O(n): 思路2:从头到尾分别遍历两个链表得到 ...
- 2D空间中求两圆的交点
出处:https://stackoverflow.com/questions/19916880/sphere-sphere-intersection-c-3d-coordinates-of-colli ...
- 算法(JAVA)----两道小小课后题
LZ最近翻了翻JAVA版的数据结构与算法,无聊之下将书中的课后题一一给做了一遍,在此给出书中课后题的答案(非标准答案,是LZ的答案,猿友们可以贡献出自己更快的算法). 1.编写一个程序解决选择问题.令 ...
- 求空间内两条直线的最近距离以及最近点的坐标(C++)
关键词:空间几何 用途:总有地方会用到吧 文章类型:C++函数展示 @Author:VShawn(singlex@foxmail.com) @Date:2016-11-19 @Lab: CvLab20 ...
- ArcGIS Engine开发之空间查询
空间查询功能是通过用户选择的空间几何体以及该几何体与当前地图中要素之间的几何关系进行空间查找,从而得到查询结果的操作. 相关类与接口 空间查询相关的类主要是SpatialFilter类,其实现的接口主 ...
- [Linux] -Docker修改空间大小
Docker默认空间大小分为两个,一个是池空间大小,另一个是容器空间大小. 池空间大小默认为:100G 容器空间大小默认为是:10G 所以修改空间大小也分为两个: 这里使用centos下的yum进行安 ...
- 3.2 一般的哈尔空间Vj
例3.2给予我们继续往下面做的动力.很明显的我们对于g(t)的逼近还是太粗糙了.很自然的,我们会想到,如果继续细分我们的短点,比如每1/2取一个值,甚至每1/4取一个值,那么就会有更好的逼近效果. 不 ...
- stl空间配置器线程安全问题补充
摘要 在上一篇博客<STL空间配置器那点事>简单介绍了空间配置器的基本实现 两级空间配置器处理,一级相关细节问题,同时简单描述了STL各组件之间的关系以及设计到的设计模式等. 在最后,又关 ...
随机推荐
- fastjson处理json
返回主页 你是风儿 博客园首页新随笔联系订阅管理 随笔 - 29 文章 - 0 评论 - 23 FastJson对于JSON格式字符串.JSON对象及JavaBean之间的相互转换 fastJson对 ...
- 四、新时间日期API
一.使用 LocalDate .LocalTime .LocalDateTime LocalDate.LocalTime.LocalDateTime 类的实例是不可变的对象,分别表示使用 ISO-86 ...
- hive 更改列的位置时遇到的问题
hive > desc formatted tb_fq; OK col_name data_type comment # col_name data_type comment name stri ...
- ruby 基础教程1-8-1
1.":class, instance_of?, :is_a?"都是Object类的方法,每个对象都可以调用 2.":class"方法用户获取对象归属类的名称 ...
- Java+Selenium 3.x 实现Web自动化 - 1.自动化准备
(一)自动化准备 说明:本文主要记录了基于公司现有项目(一个电子商务平台),从0开始实现UI自动化的历程.从准备阶段,部分内容直接省略了基础知识,一切以最终做成自动化项目为目标,难免会有晦涩之处.文章 ...
- Appium的一点一滴:Android KEYCODE键值
转自:http://blog.csdn.net/crisschan/article/details/50419963 - 电话键 键名 描述 键值 KEYCODE_CALL 拨号键 5 KEYCODE ...
- Linux命令应用大词典-第46章 其他命令
46.1 mkfontdir:创建X字体文件的索引 46.2 dumpiso:转储IEEE 1394同步信道的数据包 46.3 iconv:转换文件编码 46.4 hash:显示和删除哈希表 46.5 ...
- Objective-C 构造方法 分类 类的深入研究
构造方法 1.对象创建的原理 new的拆分两部曲 Person *p = [Person alloc]; 分配内存(+alloc) Person *p = [p init]; 初始化(-init) 合 ...
- 小组ITalk网站开发中使用到的一些技巧
----->Display属性和Visibility属性:一个清除内容和框体,另一个只清除内容而保留窗体: $('#abc').css({ 'font-size' : '12px', '-web ...
- C++clock()延时循环
函数clock(),返回程序开始执行后所用的系统时间,但是有两个复制问题. 1.clock()返回时间的单位不一定是秒 2.该函数的返回类型在某些系统上可能是Long,也可能是unsigned lon ...