BZOJ2141:排队
浅谈分块:https://www.cnblogs.com/AKMer/p/10369816.html
题目传送门:https://lydsy.com/JudgeOnline/problem.php?id=2141
第一次的答案可以直接用树状数组求。
如果交换\(pos_1\)和\(pos_2\),那么显然我不需要管\([1,pos_1-1]\)和\([pos_2+1,n]\)。
对于\([pos_1+1,pos_2-1]\)之间的每个数\(v_i\)
\(v_i<v_{pos_1}\),答案减一;\(v_i>v_{pos_1}\),答案加一;\(v_i<v_{pos_2}\),答案加一,\(v_i>v_{pos_2}\),答案减一。
对于每个块我用一个树状数组维护块内权值个数。整个的块直接查找有多少小于或者大于某个值的数的个数,零散的直接暴力扫。
时间复杂度:\(O(NlogN+M\sqrt{N}logN)\)
空间复杂度:\(O(N\sqrt{n})\)
代码如下:
#include <cmath>
#include <cstdio>
#include <algorithm>
using namespace std;
#define low(i) ((i)&(-(i)))
const int maxn=2e4+5;
int L[145],R[145];
int n,m,cnt,block,ans;
int tmp[maxn],v[maxn],bel[maxn];
int read() {
int x=0,f=1;char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
return x*f;
}
struct Tree_array {
int c[maxn];
void add(int pos,int num) {
for(int i=pos;i<=cnt;i+=low(i))
c[i]+=num;
}
int query(int pos) {
int res=0;
for(int i=pos;i;i-=low(i))
res+=c[i];
return res;
}
}T[145];
void check(int i,int l,int r) {
if(v[i]<v[l])ans--;
if(v[i]>v[l])ans++;
if(v[i]<v[r])ans++;
if(v[i]>v[r])ans--;
}
int main() {
n=read(),block=sqrt(n);
for(int i=1;i<=n;i++) {
v[i]=tmp[i]=read(),bel[i]=(i-1)/block+1;
if(bel[i]!=bel[i-1])R[bel[i-1]]=i-1,L[bel[i]]=i;
}R[bel[n]]=n;
sort(tmp+1,tmp+n+1);
cnt=unique(tmp+1,tmp+n+1)-tmp-1;
for(int i=1;i<=n;i++)
v[i]=lower_bound(tmp+1,tmp+cnt+1,v[i])-tmp;
for(int i=n;i;i--) {
ans+=T[0].query(v[i]-1);
T[0].add(v[i],1);
T[bel[i]].add(v[i],1);
}
printf("%d\n",ans);
m=read();
while(m--) {
int l=read(),r=read();
if(r<l)swap(l,r);
if(bel[l]==bel[r]) {
for(int i=l+1;i<r;i++)
check(i,l,r);
}
else {
for(int i=l+1;i<=R[bel[l]];i++)
check(i,l,r);
for(int i=L[bel[r]];i<r;i++)
check(i,l,r);
for(int i=bel[l]+1;i<bel[r];i++) {
ans-=T[i].query(v[l]-1);
ans+=T[i].query(cnt)-T[i].query(v[l]);
ans+=T[i].query(v[r]-1);
ans-=T[i].query(cnt)-T[i].query(v[r]);
}
T[bel[l]].add(v[l],-1),T[bel[l]].add(v[r],1);
T[bel[r]].add(v[l],1),T[bel[r]].add(v[r],-1);
}
if(v[l]>v[r])ans--;
if(v[l]<v[r])ans++;
swap(v[l],v[r]);
printf("%d\n",ans);
}
return 0;
}
BZOJ2141:排队的更多相关文章
- BZOJ2141 排队 树状数组 分块
原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ2141.html 题目传送门 - BZOJ2141 题意 给定一个序列 $a$ ,先输出原先的逆序对数. ...
- bzoj2141排队(辣鸡但是好写的方法)
题意很明确,也非常经典: 一个支持查询 区间中比k大的数的个数 并且支持单点修改的序列 ——因为题意可以转化为:查询这两个数中比后者大的个数.比后者小的个数.比前者大的个数.比前者小的个数(根据这4个 ...
- BZOJ2141: 排队
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2141 分块加树状数组. 离散化之后,每一个块建一个树状数组.交换x,y,与x左边的数和y右 ...
- bzoj2141排队
/* 动态求逆序对,可以树套树来写, 将交换操作理解成插入和删除比较好理解, 里层是个区间求和的线段树就好了 或者叫 带修主席树? */ #include<cstdio> #include ...
- BZOJ2141排队——树状数组套权值线段树(带修改的主席树)
题目描述 排排坐,吃果果,生果甜嗦嗦,大家笑呵呵.你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家 乐和和.红星幼儿园的小朋友们排起了长长地队伍,准备吃果果.不过因为小朋友们的身高有所区别 ...
- bzoj2141: 排队(分块+树状数组)
块套树为什么会这么快.. 先跑出原序列逆序对. 显然交换两个位置$l,r$,对$[1,l),(r,n]$里的数没有影响,所以只需要考虑$[l,r]$内的数. 设$(l,r)$内的数$a_i$,则按以下 ...
- BZOJ2141:排队(分块,树状数组)
Description 排排坐,吃果果,生果甜嗦嗦,大家笑呵呵.你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家 乐和和.红星幼儿园的小朋友们排起了长长地队伍,准备吃果果.不过因为小朋友们 ...
- 【分块】【树套树】bzoj2141 排队
考虑暴力更新的情况,设swap的是L,R位置的数.swap之后的逆序对数应该等于:之前的逆序对数+[L+1,R-1]中比 L位置的数 大的数的个数-[L+1,R-1]中比 L位置的数 小的数的个数-[ ...
- [bzoj2141][排队] (分块大法好)
Description 排排坐,吃果果,生果甜嗦嗦,大家笑呵呵.你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家乐和和.红星幼儿园的小朋友们排起了长长地队伍,准备吃果果.不过因为小朋友们的 ...
- 树套树Day1线段树套平衡树bzoj3196
您需要写一种数据结构,来维护一个有序数列,其中需要提供以下操作:1.查询k在区间内的排名2.查询区间内排名为k的值3.修改某一位值上的数值4.查询k在区间内的前驱(前驱定义为小于x,且最大的数)5.查 ...
随机推荐
- JSON.parse和JSON.stringify的作用
//JSON.parse将字符串格式json转化为json对象 var str='{"name":"lingling","age":&quo ...
- CSS3 3D旋转下拉菜单
在线演示 本地下载
- 二、linux题型
1.[root@pyrene ~]# 这里root是当前登录用户 @分割 pyrene是主机名 -:表示当前登录环境 #:表示管理员 2.在/data下面创建一个文件oldboy. ...
- Android修改init.rc和init.xx.rc文件【转】
本文转载自:https://blog.csdn.net/u013686019/article/details/47981249 一.文件简介 init.rc:Android在启动过程中读取的启动脚本文 ...
- windows环境下安装部署并启用zkui的web图形界面
在此之前的工作:不是本机部署的三个服务器最为伪集群的zookeeper环境,并将三个为服务启动起来. 然后才有了下面的工作. 1. 首先,zkui项目地址:https://github.com/Dee ...
- 查看git安装目录
有时候需要知道Git在电脑中的安装位置,这里简单介绍下: Mac平台:在命令行中输入which git, 就会显示git的安装位置了; Windows平台:打开cmd,输入where git就会显示g ...
- RHCE学习笔记 管理1 (第一、二章)
第一章 命令行访问 1.Ctrl+alt+F2~F6 切到虚拟控制台,ctrl+alt+F1 回到图形界面 2.格式 : 命令 选项 参数 [] 为可选项目 ...表示该项目任意 ...
- mysql里的ibdata1文件
mysql大多数磁盘空间被 InnoDB 的共享表空间 ibdata1 使用.而你已经启用了 innodb_file_per_table,所以问题是: ibdata1存了什么? 当你启用了innodb ...
- eclipse修改端口启动多个tomcat
参考:https://blog.csdn.net/zl544434558/article/details/47857343 在一个eclipse启动多个tomcat,修改tomcat的端口是不可以的, ...
- Tensorflow 从零开始
1.安装pip pip是一个用于管理和安装Python包的工具,类似于LINUX 的yum命令一样! 命令(Ubuntu系统):sudo apt-get install python-pip 验证安装 ...