计蒜客模拟赛D2T2 蒜头君的排序:区间逆序对(移动端点) + 树状数组
题目链接:https://nanti.jisuanke.com/t/16443
题意:
给你一个由1~n构成的正整数序列,有m组询问,每组询问要求输出[l , r]区间内的逆序对个数。
数据范围:
对于100%的数据,满足1 <= n,m <= 30000,l < r,∑ | l[i] - l[i-1] | + ∑ | r[i] - r[i-1] | <= 7 * 10^6。
题解:
如果知道区间[l , r]中的逆序对个数,那么也可以快速求出区间[l-1 , r],[l+1 , r],[l , r-1],[l , r+1]的逆序对个数。
① [l-1 , r]的个数 = [l , r]的个数 + [l , r]中比a[l-1]小的元素的个数
② [l+1 , r]的个数 = [l , r]的个数 - [l+1 , r]中比a[l]小的元素的个数
③ [l , r-1]的个数 = [l , r]的个数 - [l , r-1]中比a[r]大的元素的个数
④ [l , r+1]的个数 = [l , r]的个数 + [l , r]中比a[r+1]大的元素的个数
查询区间内比x大(小)的元素的个数用树状数组实现。
比x大的元素个数 = query(x - 1)
比x小的元素个数 = query(n) - query(x) (区间内元素总个数减去大于等于x的元素个数)
先假定现在的区间为[1 , 1],逆序对总个数为0。对于每一组询问,只要不断移动当前区间的左右端点,并同时更新答案,直至当前区间与询问区间相同即可,输出sum值。
AC Code:
#include <iostream>
#include <stdio.h>
#include <string.h>
#define MAX_N 30005 using namespace std; int n,m;
int a[MAX_N];
int dat[MAX_N]; void update(int k,int a)
{
while(k<=n)
{
dat[k]+=a;
k+=k&-k;
}
} int query(int k)
{
int sum=;
while(k>)
{
sum+=dat[k];
k-=k&-k;
}
return sum;
} void read()
{
cin>>n;
for(int i=;i<=n;i++)
{
cin>>a[i];
}
} void solve()
{
memset(dat,,sizeof(dat));
cin>>m;
int sum=;
int lef=,rig=;
update(a[],);
for(int i=;i<m;i++)
{
int l,r;
cin>>l>>r;
while(lef<l)
{
update(a[lef],-);
sum-=query(a[lef]-);
lef++;
}
while(lef>l)
{
lef--;
sum+=query(a[lef]-);
update(a[lef],);
}
while(rig<r)
{
rig++;
sum+=query(n)-query(a[rig]);
update(a[rig],);
}
while(rig>r)
{
update(a[rig],-);
sum-=query(n)-query(a[rig]);
rig--;
}
cout<<sum<<endl;
}
} int main()
{
read();
solve();
}
计蒜客模拟赛D2T2 蒜头君的排序:区间逆序对(移动端点) + 树状数组的更多相关文章
- 计蒜客模拟赛D2T3 蒜头君救人:用bfs转移状压dp
题目链接:https://nanti.jisuanke.com/t/16444 题意: 蒜头君是一个乐于助人的好孩子,这天他所在的乡村发生了洪水,有多名村民被困于孤岛上,于是蒜头君决定去背他们离开困境 ...
- 计蒜客模拟赛D1T3 蒜头君的坐骑:用dfs转移dp
题目链接:https://nanti.jisuanke.com/t/16447 题意: 蒜头君有一只坐骑,人马. 一天,蒜头君骑着他的坐骑走上了一片n*m的大荒野,一开始时,蒜头君在(1,1)点,他要 ...
- 计蒜客模拟赛D2T1 蒜头君的兔子:矩阵快速幂
题目链接:https://nanti.jisuanke.com/t/16442 题意: 有个人在第一年送了你一对1岁的兔子.这种兔子刚生下来的时候算0岁,当它在2~10岁的时候,每年都会生下一对兔子, ...
- 计蒜客模拟赛D1T2 蒜头君的树:树上节点之间最短距离和
题目链接:https://nanti.jisuanke.com/t/16446 题意: 给你一棵有n个节点的树以及每条边的长度,输出树上节点之间的最短距离和.然后进行m次操作,每次操作更改一条边的长度 ...
- 计蒜客模拟赛D1T1 蒜头君打地鼠:矩阵旋转+二维前缀和
题目链接:https://nanti.jisuanke.com/t/16445 题意: 给你一个n*n大小的01矩阵,和一个k*k大小的锤子,锤子只能斜着砸,问只砸一次最多能砸到多少个1. 题解: 将 ...
- 计蒜客模拟赛5 D2T1 成绩统计
又到了一年一度的新生入学季了,清华和北大的计算机系同学都参加了同一场开学考试(因为两校兄弟情谊深厚嘛,来一场联考还是很正常的). 不幸的是,正当老师要统计大家的成绩时,世界上的所有计算机全部瘫痪了. ...
- 计蒜客模拟赛5 D2T2 蚂蚁搬家
很久很久以前,有很多蚂蚁部落共同生活在一片祥和的村庄里.但在某一天,村庄里突然出现了一只食蚁兽,蚂蚁们为了保全性命而决定搬家. 然而这个村庄四面环山,想要离开这个村庄必须要从地洞里离开,村子里一共有 ...
- 计蒜客模拟赛 #5 (B 题) 动态点分治+线段树
虽然是裸的换根dp,但是为了在联赛前锻炼码力,强行上了点分树+线段树. 写完+调完总共花了不到 $50$ 分钟,感觉还行. code: #include <bits/stdc++.h> # ...
- 计蒜客D2T2 蒜头君的排序(动态维护树状数组)
蒜头君的排序(sort) 2000ms 262144K 蒜头君是一个爱思考的好孩子,这一天他学习了冒泡排序,于是他就想,把一个乱序排列通过冒泡排序排至升序需要多少次交换,这当然难不倒他,于是他想来点刺 ...
随机推荐
- Java内部类与final关键字详解
一.内部类的几种创建方法: 1.成员内部类 class Outer{ private int i = 1; class Inner{ public void fun() {System.out.pri ...
- H5学习第二周
怎么说,在各种感觉中h5学习的第二周已经过来了,先总结一下,感觉学习h5是一件让我爱恨交加的事,学会一些新的知识并把它成功运行出来的时候是非常激动和兴奋的,但是有时候搞不懂一个标签或者属性的时候,就有 ...
- eclipse从SVN检出项目之后,项目出错
今天公司把我分配到另一个项目组工作,然后下午使用SVN检出项目,出了问题 1.从SVN检出项目之后,要导入jar包.结果右键项目找不到Build Path,问了大牛才知道是这里的问题,一共四个步骤解决 ...
- Centos 6.x 部署pptp VPN
安装 系统检测不到PPTP的时候 使用一下方法安装PPTP 下载地址:http://poptop.sourceforge.net/yum/stable/packages rpm -ivh http: ...
- tkinter模块常用参数(python3)
1.使用tkinter.Tk() 生成主窗口(root=tkinter.Tk()):root.title('标题名') 修改框体的名字,也可在创建时使用className参数来命名:root.r ...
- Complete
complete为动画结束时的回调函数,在无限循环模式下(设置loop: true) 该回调函数将不会执行,但是有规定次数的循环模式下(比如设置设置loop: 3) 该回调函数 将只会在最后一次循环结 ...
- 虚函数&多态
对于经常被问到的虚函数和多态的问题,发现百度百科回答得十分详细,所以自己在百度百科上的解释进行总结 一.虚函数 (1)虚函数简介:在某基类中声明为virtual并在一个或者多个派生类中被重新定义的成员 ...
- ArrayList源码浅析(jdk1.8)
ArrayList的实质就是动态数组.所以可以通过下标准确的找到目标元素,因此查找的效率高.但是添加或删除元素会涉及到大量元素的位置移动,所以效率低. 一.构造方法 ArrayList提供了3个构造方 ...
- HTML5中a标签的锚点使用
前几天有个用户问我关于在线手册功能里的锚点问题.因为他通过代码发现,在编辑手册内容时,锚点的设置是通过id选择器来制定的,而不是带有name属性的a标签.其实这是HTML5和HTML4(XHTML)等 ...
- Codeforces_499C:Crazy Town(计算几何)
题目链接 给出点A(x1,y1),B(x2,y2),和n条直线(ai,bi,ci,aix + biy + ci = 0),求A到B穿过多少条直线 枚举每条直线判断A.B是否在该直线两侧即可 #incl ...