浅谈分块: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:排队的更多相关文章

  1. BZOJ2141 排队 树状数组 分块

    原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ2141.html 题目传送门 - BZOJ2141 题意 给定一个序列 $a$ ,先输出原先的逆序对数. ...

  2. bzoj2141排队(辣鸡但是好写的方法)

    题意很明确,也非常经典: 一个支持查询 区间中比k大的数的个数 并且支持单点修改的序列 ——因为题意可以转化为:查询这两个数中比后者大的个数.比后者小的个数.比前者大的个数.比前者小的个数(根据这4个 ...

  3. BZOJ2141: 排队

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2141 分块加树状数组. 离散化之后,每一个块建一个树状数组.交换x,y,与x左边的数和y右 ...

  4. bzoj2141排队

    /* 动态求逆序对,可以树套树来写, 将交换操作理解成插入和删除比较好理解, 里层是个区间求和的线段树就好了 或者叫 带修主席树? */ #include<cstdio> #include ...

  5. BZOJ2141排队——树状数组套权值线段树(带修改的主席树)

    题目描述 排排坐,吃果果,生果甜嗦嗦,大家笑呵呵.你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家 乐和和.红星幼儿园的小朋友们排起了长长地队伍,准备吃果果.不过因为小朋友们的身高有所区别 ...

  6. bzoj2141: 排队(分块+树状数组)

    块套树为什么会这么快.. 先跑出原序列逆序对. 显然交换两个位置$l,r$,对$[1,l),(r,n]$里的数没有影响,所以只需要考虑$[l,r]$内的数. 设$(l,r)$内的数$a_i$,则按以下 ...

  7. BZOJ2141:排队(分块,树状数组)

    Description 排排坐,吃果果,生果甜嗦嗦,大家笑呵呵.你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家 乐和和.红星幼儿园的小朋友们排起了长长地队伍,准备吃果果.不过因为小朋友们 ...

  8. 【分块】【树套树】bzoj2141 排队

    考虑暴力更新的情况,设swap的是L,R位置的数.swap之后的逆序对数应该等于:之前的逆序对数+[L+1,R-1]中比 L位置的数 大的数的个数-[L+1,R-1]中比 L位置的数 小的数的个数-[ ...

  9. [bzoj2141][排队] (分块大法好)

    Description 排排坐,吃果果,生果甜嗦嗦,大家笑呵呵.你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家乐和和.红星幼儿园的小朋友们排起了长长地队伍,准备吃果果.不过因为小朋友们的 ...

  10. 树套树Day1线段树套平衡树bzoj3196

    您需要写一种数据结构,来维护一个有序数列,其中需要提供以下操作:1.查询k在区间内的排名2.查询区间内排名为k的值3.修改某一位值上的数值4.查询k在区间内的前驱(前驱定义为小于x,且最大的数)5.查 ...

随机推荐

  1. Emgu在引用openCV时提示:无法加载 DLL“opencv_core2410”: 找不到指定的模块。

    在引用开源代码openCV时发现了如下问题: 无法加载 DLL“opencv_core2410”: 找不到指定的模块. (异常来自 HRESULT:0x8007007E). 解决方法如下: 将Emgu ...

  2. Shell编程之for和select循环

    一.for和select循环 1.for循环语法 for 变量名 in 变量取值列表 do 指令... done C语言型for循环 for ((exp1; exp2; exp3)) do 指令... ...

  3. openpyxl之excel操作

    一.读取excel中内容 1.导入模块 : from openpyxl import load_workbook 2.打开excel : workbook = load_workbook(" ...

  4. Nginx 常见报错

    Nginx 常见报错 启动报错:[emerg]: bind() to 0.0.0.0:80 failed (98: Address already in use) 原因:这个是nginx重启时经常遇到 ...

  5. @MarkFan 口语练习录音 20140423 [风雨哈佛路.Homeless To Harvard口语录音]

    世界在转动,你只是一粒尘埃 没有你,世界照样在转 现实不会按照你的意识去改变的 一些人的需求 一些人的意志要比你更强 严酷的生活会让人不知所措 所以他们久久地困在挫败中 我们生气地抱怨,而对整体的形势 ...

  6. Oracle、Mysql、SqlServer创建表和给表和字段加注释

    一.Oracle --创建表 create table test (      id varchar2(200) primary key not null,      sort number,     ...

  7. MyEclipse+PyDev配置搭建Python开发环境

    打开help-> install from catalog 输入pydev查找并安装pydev 根据提示进行安装,安装完后重启myeclipse

  8. psd文件中截取固定大小的图片

    1.选择需要操作的图层 使用选框工具, 设置固定大小和固定大小的值,在图层上拉取选区 2.使用移动工具  使用垂直.水平居中 使选择的icon在选区块中间 3.再选择好块区域调整好位置后 使用截取工具 ...

  9. Boostarp-响应式

    一.响应式 响应式介绍 - 响应式布局是什么? 同一个网页在不同的终端上呈现不同的布局等 - 响应式怎么实现的? 1. CSS3 media query 媒体查询 2. JS去控制网页的布局和样式等 ...

  10. JMeter ——Test fragment

    fragment 为片段,可以是一个不完整的用例.比如你可以把一个http请求保存为fragment,如果不这样做的话,你是必须先要添加一个测试计划-线程组-http请求的.你可以把某步骤一系列的请求 ...