luogu1975 排队(分块)
luogu1975 排队(分块)
给你一个长度为n的序列,每次交换给定的两个数,输出每次操作后的逆序对个数。
首先考虑求出刚开始的逆序对。接着相当于带修改的求区间中比x大的数。
可以用分块,每个块内排序,然后维护排序后的块。每次查询,块外二分,块内暴力。
#include <cmath>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn=2e4+5, maxbar=2e2+5;
int n, a[maxn], b[maxn], ans;
int m, barlen, bel[maxn], cntbar;
struct node{
int id, v;
}sted[maxn], t;
bool cmp(const node &a, const node &b){ return a.v<b.v; }
int tmp[maxn];
void msort(int l, int r){ //[l, r)
if (l==r-1) return;
int mid=(l+r)>>1;
msort(l, mid); msort(mid, r);
int i=l, j=mid, cnt=0;
while (i<mid&&j<r){
if (b[i]<=b[j]) tmp[cnt++]=b[i++], ans+=j-mid;
else tmp[cnt++]=b[j++];
}
while (i<mid) tmp[cnt++]=b[i++], ans+=j-mid;
while (j<r) tmp[cnt++]=b[j++];
for (int i=0; i<cnt; ++i) b[l+i]=tmp[i];
}
//在[l, r)中大于x的数有几个
int bigger(int l, int r, int x){
if (l>=r) return 0;
int cnt=0; int bl=bel[l]+1, br=bel[r-1]-1;
if (bel[l]==bel[r-1]){
for (int i=l; i<r; ++i) if (a[i]>x) ++cnt;
return cnt;
}
t.v=x;
for (int i=bl; i<=br; ++i)
cnt-=upper_bound(sted+i*barlen, sted+(i+1)*barlen, t, cmp)
-(sted+(i+1)*barlen);
for (int i=l; i==l||bel[i]==bel[i-1]; ++i)
if (a[i]>x) ++cnt;
for (int i=r-1; i==r-1||bel[i]==bel[i+1]; --i)
if (a[i]>x) ++cnt;
return cnt;
}
//在[l, r)中小于x的数有几个
int smaller(int l, int r, int x){
if (l>=r) return 0;
int cnt=0; int bl=bel[l]+1, br=bel[r-1]-1;
if (bel[l]==bel[r-1]){
for (int i=l; i<r; ++i) if (a[i]<x) ++cnt;
return cnt;
}
t.v=x;
for (int i=bl; i<=br; ++i)
cnt+=lower_bound(sted+i*barlen, sted+(i+1)*barlen, t, cmp)
-(sted+i*barlen);
for (int i=l; i==l||bel[i]==bel[i-1]; ++i)
if (a[i]<x) ++cnt;
for (int i=r-1; i==r-1||bel[i]==bel[i+1]; --i)
if (a[i]<x) ++cnt;
return cnt;
}
//维护sorted数组
int change(int pos, int num){
for (int i=bel[pos]*barlen; i<(bel[pos]+1)*barlen; ++i)
if (sted[i].id==pos){ pos=i; break; }
sted[pos].v=num;
while (sted[pos].v>sted[pos+1].v&&bel[pos]==bel[pos+1])
swap(sted[pos], sted[pos+1]), ++pos;
while (sted[pos].v<sted[pos-1].v&&bel[pos]==bel[pos-1])
swap(sted[pos], sted[pos-1]), --pos;
return pos;
}
void modify(int pos, int num){
ans-=bigger(0, pos, a[pos]);
ans-=smaller(pos, n, a[pos]);
a[pos]=num; change(pos, num);
ans+=bigger(0, pos, num);
ans+=smaller(pos, n, num);
}
int main(){
scanf("%d", &n); barlen=sqrt(n);
for (int i=0; i<n; ++i){
scanf("%d", &a[i]);
b[i]=sted[i].v=a[i]; sted[i].id=i;
}
msort(0, n); printf("%d\n", ans);
for (int i=0; i<n; ++i) bel[i]=i/barlen; cntbar=bel[n-1]+1;
for (int i=0; i<cntbar; ++i) \
sort(sted+i*barlen, sted+min((i+1)*barlen, n), cmp);
scanf("%d", &m); int x, y, tmp;
for (int i=0; i<m; ++i){
scanf("%d%d", &x, &y); --x; --y; tmp=a[x];
modify(x, a[y]); modify(y, tmp);
//for (int j=0; j<n; ++j) printf("%d ", sted[j].v);
//puts("");
printf("%d\n", ans);
}
return 0;
}
luogu1975 排队(分块)的更多相关文章
- Bzoj 2141: 排队 分块,逆序对,树状数组
2141: 排队 Time Limit: 4 Sec Memory Limit: 259 MBSubmit: 1310 Solved: 517[Submit][Status][Discuss] D ...
- bzoj 2141 : 排队 分块
题目链接 2141: 排队 Time Limit: 4 Sec Memory Limit: 259 MBSubmit: 1169 Solved: 465[Submit][Status][Discu ...
- bzoj 1699: [Usaco2007 Jan]Balanced Lineup排队 分块
1699: [Usaco2007 Jan]Balanced Lineup排队 Time Limit: 5 Sec Memory Limit: 64 MB Description 每天,农夫 John ...
- BZOJ2141:排队(分块,树状数组)
Description 排排坐,吃果果,生果甜嗦嗦,大家笑呵呵.你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家 乐和和.红星幼儿园的小朋友们排起了长长地队伍,准备吃果果.不过因为小朋友们 ...
- 【bzoj2141】排队 分块+树状数组
题目描述 排排坐,吃果果,生果甜嗦嗦,大家笑呵呵.你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家乐和和.红星幼儿园的小朋友们排起了长长地队伍,准备吃果果.不过因为小朋友们的身高有所区别, ...
- [bzoj2141][排队] (分块大法好)
Description 排排坐,吃果果,生果甜嗦嗦,大家笑呵呵.你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家乐和和.红星幼儿园的小朋友们排起了长长地队伍,准备吃果果.不过因为小朋友们的 ...
- BZOJ_2141_排队_树状数组+分块
BZOJ2141_排队_树状数组+分块 Description 排排坐,吃果果,生果甜嗦嗦,大家笑呵呵.你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家 乐和和.红星幼儿园的小朋友们排起了 ...
- 【BZOJ2141】排队 树状数组+分块
[BZOJ2141]排队 Description 排排坐,吃果果,生果甜嗦嗦,大家笑呵呵.你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家乐和和.红星幼儿园的小朋友们排起了长长地队伍,准备 ...
- Luogu-1975 [国家集训队]排队
Luogu-1975 [国家集训队]排队 题面 Luogu-1975 题解 题意:给出一个长度为n的数列以及m个交换两个数的操作,问每次操作后逆序对数量 时间,下标和数的大小三维偏序,,,把交换操作看 ...
随机推荐
- hdu 2955 Robberies(01背包)
Robberies Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total S ...
- POJ 1258 Agri-Net(Prim算法)
题意:n个农场,求把所有农场连接起来所需要最短的距离. 思路:prim算法 课本代码: //prim算法 #include<iostream> #include<stdio.h> ...
- unity破解步骤
1.选择unity的安装目录 C:\Programe Files (x86)\Unity\Editor 2.点击patch 3.使用random生成序列号 4.使用Cre Lic生成授权文件
- WC2010 BZOJ1758 重建计划_长链剖分
题目大意: 求长度$\in [L,U]$的路径的最大边权和平均值. 题解 首先二分就不用说了,分数规划大家都懂. 这题有非常显然的点分治做法,但还是借着这个题学一波长链剖分. 其长链剖分本身也没啥,就 ...
- Gym 101142C :CodeCoder vs TopForces(强连通算法)
题意:N个人,每个人有a属性和b属性,如果一个人的a或者b大于另外一个人,我们说这个人可以打败那个人.且这种关系可以传递.对于每个人,输出他可以打败多少人.(保证每个a不相同,保证每个b不相同. 思路 ...
- bzoj 3514: GERALD07加强版 lct+可持久化线段树
题目大意: N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. 题解: 这道题考试的时候没想出来 于是便爆炸了 结果今天下午拿出昨天准备的题表准备做题的时候 题表里就有这题 ...
- P1607 [USACO09FEB]庙会班车Fair Shuttle
题目描述 Although Farmer John has no problems walking around the fair to collect prizes or see the shows ...
- docker 局域网仓库(registry)
sudo docker pull daocloud.io/registry 安装仓库(registry) 使用daocloud/aliyun镜像吧,官网仓库真心没法用 sudo docker r ...
- asp.net异常处理和错误页配置
最近做一个项目,直接拷贝了前辈写的程序,结果报错了查了半天都没查出原因,也看不出哪里报错,最后发现有一个错误被try...catch了,所以我们做项目的时候一般不需要try...catch. 假设所有 ...
- redis的read error on connection错误解决
昨日,公司php调用redis报错:read error on connection 2015-01-29 23:59:050.13330000,redis存放的是用户session. 在网上查询,大 ...