bzoj2141_排队
题意
给定\(n\)个数,每次交换两个数,输出交换后的逆序数。
分析
- 交换两个数只会影响到对应区间内的逆序数,具体为减少区间\([l+1,r-1]\)中比\(a[r]\)大的数的个数,增加比\(a[r]\)大的数的个数,减少比大的数的个数,\(a[l]\)增加比\(a[l]\)小的数的个数。
- 转化为单点修改+查询区间值域个数,树套树。
- 思路不难想,写完调了一年,注意几个点
- 外层bit大小是的是序列长度n,不是离散化后的值域ns。
- 数据不保证\(l<=r\)。
- 注意相同元素。
- 最后要判断\(a[l]\)和\(a[r]\)的大小关系,除去相等。
代码
#include <bits/stdc++.h>
using namespace std;
const int N=2e4+50;
int n,ns,m,a[N],l,r,tr[N*20],x[N],y[N],c1,c2;
struct Orz{
vector<int> a;
void init(){
a.clear();
}
int siz(){
return a.size();
}
void add(int x){
a.push_back(x);
}
void work(){
sort(a.begin(),a.end());
a.erase(unique(a.begin(),a.end()),a.end());
}
int idx(int v){
return lower_bound(a.begin(),a.end(),v)-a.begin()+1;
}
int val(int i){
return a[i-1];
}
}orz;
struct HJT{
#define mid (l+r)/2
int tot,sum[N*200],ls[N*200],rs[N*200];
void update(int &x,int l,int r,int v,int add){
if(!x){
x=++tot;
}
sum[x]+=add;
if(l<r){
if(v<=mid){
update(ls[x],l,mid,v,add);
}else{
update(rs[x],mid+1,r,v,add);
}
}
}
int query(int l,int r,int k){
if(k==0){
return 0;
}
if(r<=k){
int ans=0;
for(int i=1;i<=c1;i++){
ans-=sum[x[i]];
}
for(int i=1;i<=c2;i++){
ans+=sum[y[i]];
}
return ans;
}
if(k<=mid){
for(int i=1;i<=c1;i++){
x[i]=ls[x[i]];
}
for(int i=1;i<=c2;i++){
y[i]=ls[y[i]];
}
return query(l,mid,k);
}else{
int ans=0;
for(int i=1;i<=c1;i++){
ans-=sum[ls[x[i]]];
}
for(int i=1;i<=c2;i++){
ans+=sum[ls[y[i]]];
}
for(int i=1;i<=c1;i++){
x[i]=rs[x[i]];
}
for(int i=1;i<=c2;i++){
y[i]=rs[y[i]];
}
return ans+query(mid+1,r,k);
}
}
}ac;
struct BIT{
int lowbit(int x){
return x&(-x);
}
void modify(int i,int x){
int k=a[i];
while(i<=n){
ac.update(tr[i],1,ns,k,x);
i+=lowbit(i);
}
}
int query(int l,int r,int xi,int yi){
if(xi>yi){
return 0;
}
c1=c2=0;
for(int i=l-1;i;i-=lowbit(i)){
x[++c1]=tr[i];
}
for(int i=r;i;i-=lowbit(i)){
y[++c2]=tr[i];
}
int R=ac.query(1,ns,yi);
c1=c2=0;
for(int i=l-1;i;i-=lowbit(i)){
x[++c1]=tr[i];
}
for(int i=r;i;i-=lowbit(i)){
y[++c2]=tr[i];
}
int L=ac.query(1,ns,xi-1);
return R-L;
}
}bit;
int main(){
// freopen("in.txt","r",stdin);
scanf("%d",&n);
orz.init();
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
orz.add(a[i]);
}
orz.work();
ns=orz.siz();
int ans=0;
for(int i=1;i<=n;i++){
a[i]=orz.idx(a[i]);
bit.modify(i,1);
ans+=bit.query(1,i,a[i]+1,ns);
}
printf("%d\n",ans);
scanf("%d",&m);
for(int i=1;i<=m;i++){
scanf("%d%d",&l,&r);
if(l>r){
swap(l,r);
}
if(l==r){
printf("%d\n",ans);
continue;
}
if(r-l>=2){
int ta=bit.query(l+1,r-1,a[r]+1,ns);
int tb=bit.query(l+1,r-1,a[l]+1,ns);
int tc=bit.query(l+1,r-1,1,a[r]-1);
int td=bit.query(l+1,r-1,1,a[l]-1);
ans-=ta;
ans+=tc;
ans+=tb;
ans-=td;
}
if(a[l]<a[r]){
ans++;
}else if(a[l]>a[r]){
ans--;
}
bit.modify(l,-1);
bit.modify(r,-1);
swap(a[l],a[r]);
bit.modify(l,1);
bit.modify(r,1);
printf("%d\n",ans);
}
return 0;
}
bzoj2141_排队的更多相关文章
- BZOJ_2141_排队_树状数组+分块
BZOJ2141_排队_树状数组+分块 Description 排排坐,吃果果,生果甜嗦嗦,大家笑呵呵.你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家 乐和和.红星幼儿园的小朋友们排起了 ...
- C++ 事件驱动型银行排队模拟
最近重拾之前半途而废的C++,恰好看到了<C++ 实现银行排队服务模拟>,但是没有实验楼的会员,看不到具体的实现,正好用来作为练习. 模拟的是银行的排队叫号系统,所有顾客以先来后到的顺序在 ...
- bzoj 2729: [HNOI2012]排队
2729: [HNOI2012]排队 Time Limit: 10 Sec Memory Limit: 128 MB Description 某中学有 n 名男同学,m 名女同学和两名老师要排队参加体 ...
- bzoj 2141: 排队
2141: 排队 Time Limit: 4 Sec Memory Limit: 259 MB Description 排排坐,吃果果,生果甜嗦嗦,大家笑呵呵.你一个,我一个,大的分给你,小的留给我, ...
- 可重入锁 公平锁 读写锁、CLH队列、CLH队列锁、自旋锁、排队自旋锁、MCS锁、CLH锁
1.可重入锁 如果锁具备可重入性,则称作为可重入锁. ========================================== (转)可重入和不可重入 2011-10-04 21:38 这 ...
- hdu 1872(看病要排队)(优先队列)
看病要排队 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- 赴美工作常识(Part 6 - 绿卡排队)
上一篇<赴美工作常识(Part 5 - 绿卡优先级)>解释完排队的优先级是怎么确定的,以及 PERM 和 I–140 表的意义,接下来就要解释一下队具体是怎么排的以及排到之后的 I–485 ...
- hdu 1873 看病要排队(优先级队列)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1873 题目大意: 三个医生看病,病人排队看病,病人有优先级,优先级高的提前看病,同样的优先级按先后.I ...
- 排队打饭 sdut 2443【最简单的贪心法应用举例】
排队打饭 Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^ 题目描述 题目链接:http://acm.sdut.edu.cn/sdutoj/p ...
随机推荐
- 夯实Java基础(十一)——内部类
1.内部类的概念 内部类顾名思义:将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类.对于很多Java初学者来说,内部类学起来真的是一头雾水,根本理解不清楚是个什么东西,包括我自己(我太菜 ...
- 案例实战:每日上亿请求量的电商系统,JVM年轻代垃圾回收参数如何优化?
出自:http://1t.click/7TJ 目录: 案例背景引入 特殊的电商大促场景 抗住大促的瞬时压力需要几台机器? 大促高峰期订单系统的内存使用模型估算 内存到底该如何分配? 新生代垃圾回收优化 ...
- Java虚拟机学习笔记(二)--- 判断对象是否存活
Java堆中存放着所有的对象实例,垃圾收集器在堆进行回收之前,需要判断对象是“存活”还是“死亡”(即不可能再被任何途径引用的对象). 最常见的一种判断对象是否存活算法是引用计数算法, 给对象加一个引用 ...
- 帝国CMS(EmpireCMS) v7.5后台getshell分析(CVE-2018-18086)
帝国CMS(EmpireCMS) v7.5后台getshell分析(CVE-2018-18086) 一.漏洞描述 EmpireCMS 7.5版本及之前版本在后台备份数据库时,未对数据库表名做验证,通过 ...
- Amazon S3 分布式存储的 python 接口实现
Amazon s3 是一种分布式的对象存储.用键值对的方式,来存储数据.其中,存入的所有数据都是一个对象(object),每一个对象都有一个键(key)存在. 具有非常方便的 web 访问接口,以及权 ...
- 配置Oracle透明网关用以连接 SQLServer经验总结
一.情景介绍 业务中设计两个不同的系统,系统1和系统2,两个系统分别使用的是Oracle和SQLServer数据库.现需要在系统1的数据库中直接查询系统2数据库的数据.即在Oracle中执行SQL ...
- Oracle中的通用函数
1.nvl(列,默认值)函数处理null select nvl(null,3),nvl(4,3) from dual 结果显示为3,4.因为nvl中的第一个为null时,返回结果为第二个值,第一 ...
- 思科根据键值获取OID方法
一.打开思科网站官网 https://www.cisco.com/ 二.按下图路径选择 三.点击MIB Locator 四.选择"SNMP Object Navigator" 五. ...
- 人脸识别开发套件RJ45、继电器、OTG、RS232接口说明
人脸识别开发套件RJ45.继电器.OTG.RS232接口说明 接口说明 D801A 人脸抓拍识别一体机是一款高性能.高可靠性的人脸识别类产品.依托深度学习算法扩展人脸库数量,准确率更高,支 ...
- Java基础之多态和泛型浅析
Java基础之多态和泛型浅析 一.前言: 楼主看了许多资料后,算是对多态和泛型有了一些浅显的理解,这里做一简单总结 二.什么是多态? 多态(Polymorphism)按字面的意思就是“多种状态”.在面 ...