BZOJ 2141 排队(分块+树状数组)
2024-10-21 06:01:55
题意
第一行为一个正整数n,表示小朋友的数量;第二行包含n个由空格分隔的正整数h1,h2,…,hn,依次表示初始队列中小朋友的身高;第三行为一个正整数m,表示交换操作的次数;以下m行每行包含两个正整数ai和bi,表示交换位置ai与位置bi的小朋友。
输出文件共m行,第i行一个正整数表示交换操作i结束后,序列的杂乱程度(逆序对数)。
1≤m≤2*10^3,1≤n≤2*104,1≤hi≤109,ai≠bi,1≤ai,bi≤n。
题解
难受,PE看成RE,下了数据手测20组发现没有问题,最后发现多了一个endl;
然后有重复但并不用去重。
分块做法
首先离散化,分块,对于每块建立一个树状数组,保存这个块中的所有元素
然后对于每个询问(x,y) (x<y) 两侧的数是没有影响的,区间(x,y)的数a[i]讨论如下:
a[i]<a[x] --ans
a[i]>a[x] ++ans
a[i]<a[y] ++ans
a[i]>a[y] --ans
然后对于块中的树状数组处理,块外的暴力
然后附上分块VSCDQ(上面的是分块)
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=;
int n,a[N],b[N],block[N],Block,size[N],L[N],R[N],m,tr[][N],ans;
int lowbit(int x){
return x&-x;
}
void add(int id,int x,int w){
for(int i=x;i<=n;i+=lowbit(i)){
tr[id][i]+=w;
}
}
int getsum(int id,int x){
int tmp=;
for(int i=x;i;i-=lowbit(i)){
tmp+=tr[id][i];
}
return tmp;
}
int main(){
// freopen("20.in","r",stdin);
// freopen("xdx.out","w",stdout);
scanf("%d",&n);
Block=sqrt(n);
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
b[i]=a[i];
block[i]=(i-)/Block+;
size[block[i]]++;
if(!L[block[i]])L[block[i]]=i;
R[block[i]]=i;
}
sort(b+,b++n);
int tot=unique(b+,b++n)-b-;
for(int i=;i<=n;i++){
a[i]=lower_bound(b+,b++tot,a[i])-b;
}
// cout<<endl;
for(int i=;i<=n;i++){
add(block[i],a[i],);
}
for(int i=n;i>=;i--){
add(,a[i],);
ans+=getsum(,a[i]-);
}
scanf("%d",&m);
printf("%d\n",ans);
for(int i=;i<=m;i++){
int x,y;
scanf("%d%d",&x,&y);
if(x>y)swap(x,y);
if(block[x]+>=block[y]){
for(int i=x+;i<=y-;i++){
if(a[x]>a[i])ans--;if(a[x]<a[i])ans++;
if(a[y]<a[i])ans--;if(a[y]>a[i])ans++;
}
}
else{
for(int i=block[x]+;i<=block[y]-;i++){
ans-=getsum(i,a[x]-)+size[i]-getsum(i,a[y]);
ans+=getsum(i,a[y]-)+size[i]-getsum(i,a[x]);
}
for(int i=x+;i<=R[block[x]];i++){
if(a[x]>a[i])ans--;if(a[x]<a[i])ans++;
if(a[y]<a[i])ans--;if(a[y]>a[i])ans++;
}
for(int i=L[block[y]];i<=y-;i++){
if(a[x]>a[i])ans--;if(a[x]<a[i])ans++;
if(a[y]<a[i])ans--;if(a[y]>a[i])ans++;
}
}
if(a[x]>a[y])ans--;
if(a[x]<a[y])ans++;
add(block[x],a[x],-);add(block[x],a[y],);
add(block[y],a[y],-);add(block[y],a[x],);
swap(a[x],a[y]);
printf("%d\n",ans);
}
return ;
}
最新文章
- iOS TableView如何刷新指定的cell或section
- Java2_J2EE体系架构
- python suds 一坑
- 5分钟破解wpa2密码(转)
- hdu 1232 畅通工程 解题报告
- linux编辑器 vi的使用
- 03-树1. List Leaves (25)
- UILabel显示html文本
- nest expression &;amp; Pyparsing
- 获取控件id
- java进制转换(无视正负数的差别)
- CF 291E. Tree-String Problem [dfs kmp trie图优化]
- 爽翻天!告别Java。一起来使用kotlin开发完整客户端
- Centos7 安装gitLab
- vmware10.0.1安装redhat linux6.2每次启动vm崩溃问题解决!
- 解决SVN不显示绿色图标问题
- 异常: The server time zone value &#39;&#214;&#208;&#185;&#250;&#177;&#234;&#215;&#188;&#202;&#177;&#188;&#228;&#39; is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configurat
- CentOS 6下 Oracle11gR2 设置开机自启动
- Jquery消息提示插件toastr使用
- 混沌分形之迭代函数系统(IFS)
热门文章
- Ubuntu 14.04下从源码安装qt4.x
- STM8S103汇编文档和注意
- bzoj4551 [HEOI2016]树
- Java XSSF 导出excel 工具类
- YUM安装MONGODB发生Error in PREIN scriptlet in rpm package mongodb-enterprise-server-4.0.2-1.el6.x86_64错误
- C++ vector基本用法
- 紫书 例题8-10 UVa 714 (二分答案)
- Uart,IIC和SPI的区别
- 【CS round 34】Minimize Max Diff
- 【codeforces 340B】Maximal Area Quadrilateral