洛谷 P1975 [国家集训队]排队 Lebal:块内排序+树状数组
题目描述
排排坐,吃果果,生果甜嗦嗦,大家笑呵呵。你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家乐和和。
红星幼儿园的小朋友们排起了长长地队伍,准备吃果果。不过因为小朋友们的身高有所区别,排成的队伍高低错乱,极不美观。设第i个小朋友的身高为hi,我们定义一个序列的杂乱程度为:满足i<j且hi>hj的(i,j)数量。
幼儿园阿姨每次会选出两个小朋友,交换他们的位置,请你帮忙计算出每次交换后,序列的杂乱程度。为方便幼儿园阿姨统计,在未进行任何交换操作时,你也应该输出该序列的杂乱程度。
输入输出格式
输入格式:
第一行为一个正整数n,表示小朋友的数量;
第二行包含n个由空格分隔的正整数h1,h2,…,hn,依次表示初始队列中小朋友的身高;
第三行为一个正整数m,表示交换操作的次数;
以下m行每行包含两个正整数ai和bi,表示交换位置ai与位置bi的小朋友。
输出格式:
输出文件共m+1行,第i行一个正整数表示交换操作i结束后,序列的杂乱程度。
输入输出样例
说明
【样例说明】
未进行任何操作时,(2,3)满足条件;
操作1结束后,序列为130 140 150,不存在满足i<j且hi>hj的(i,j)对;
操作2结束后,序列为150 140 130,(1,2),(1,3),(2,3)共3对满足条件的(i,j)。
对于15%的数据, n,m \le 15n,m≤15 ;
对于30%的数据, n,m \le 200n,m≤200 ;
在剩下的70%数据中:
存在15%的数据, h_ihi 各不相同;
存在15%的数据, 1^{10} \le h_i \le 1^{60}110≤hi≤160 ;
以上两类数据不存在交集。
对于100%的数据, 1 \le m \le 2\times 10^31≤m≤2×103 , 1 \le n \le 2 \times 10^41≤n≤2×104 , 1 \le h_i \le 10^91≤hi≤109 , a_i \ne b_iai≠bi , 1 \le a_i,b_i \le n1≤ai,bi≤n。
代码
直接暴力分块,然后在每一个块内排序。
查询时可以在每一个块内二分。
#include <cmath>
#include <cstdio>
#include <iostream>
#include <algorithm>
#define M 210
#define N 20101 using namespace std; int n, m, t, S, C, ans;
int a[N], b[N], c[N], st[M], ed[M], belong[N], sorted[M][M], len[M]; inline int read()
{
int x = 0, f = 1;
char ch = getchar();
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0';
return x * f;
} inline int query(int x)
{
int ret = 0;
for(; x; x -= x & -x) ret += c[x];
return ret;
} inline void add(int x)
{
for(; x <= m; x += x & -x) c[x]++;
} inline void init()
{
int i, j;
S = sqrt(n);
for(i = 1; i <= n; i += S)
{
st[++C] = i;
ed[C] = min(i + S - 1, n);
len[C] = ed[C] - st[C] + 1;
}
for(i = 1; i <= C; i++)
{
for(j = st[i]; j <= ed[i]; j++)
belong[j] = i, sorted[i][j - st[i] + 1] = a[j];
sort(sorted[i] + 1, sorted[i] + len[i] + 1);
}
} inline void solve(int x, int y)
{
if(x > y) swap(x, y);
int i, l = belong[x], r = belong[y], tmp;
if(l == r)
for(i = x + 1; i < y; i++)
{
ans -= (a[i] < a[x]);
ans += (a[i] > a[x]);
ans -= (a[i] > a[y]);
ans += (a[i] < a[y]);
}
else
{
for(i = l + 1; i < r; i++)
{
ans -= lower_bound(sorted[i] + 1, sorted[i] + len[i] + 1, a[x]) - sorted[i] - 1;
ans += len[i] - (upper_bound(sorted[i] + 1, sorted[i] + len[i] + 1, a[x]) - sorted[i]) + 1;
ans -= len[i] - (upper_bound(sorted[i] + 1, sorted[i] + len[i] + 1, a[y]) - sorted[i]) + 1;
ans += lower_bound(sorted[i] + 1, sorted[i] + len[i] + 1, a[y]) - sorted[i] - 1;
}
for(i = x + 1; i <= ed[l]; i++)
{
ans -= (a[i] < a[x]);
ans += (a[i] > a[x]);
ans -= (a[i] > a[y]);
ans += (a[i] < a[y]);
}
for(i = st[r]; i < y; i++)
{
ans -= (a[i] < a[x]);
ans += (a[i] > a[x]);
ans -= (a[i] > a[y]);
ans += (a[i] < a[y]);
}
}
if(a[x] > a[y]) ans--;
if(a[x] < a[y]) ans++;
swap(a[x], a[y]);
for(i = st[l]; i <= ed[l]; i++) sorted[l][i - st[l] + 1] = a[i];
for(i = st[r]; i <= ed[r]; i++) sorted[r][i - st[r] + 1] = a[i];
sort(sorted[l] + 1, sorted[l] + len[l] + 1);
sort(sorted[r] + 1, sorted[r] + len[r] + 1);
} int main()
{
int i, x, y;
n = read();
for(i = 1; i <= n; i++) a[i] = b[i] = read();
sort(b + 1, b + n + 1);
m = unique(b + 1, b + n + 1) - b - 1;
for(i = 1; i <= n; i++)
{
a[i] = lower_bound(b + 1, b + m + 1, a[i]) - b;
ans += i - query(a[i]) - 1, add(a[i]);
}
printf("%d\n", ans);
init();
t = read();
while(t--)
{
x = read();
y = read();
solve(x, y);
printf("%d\n", ans);
}
return 0;
}
洛谷 P1975 [国家集训队]排队 Lebal:块内排序+树状数组的更多相关文章
- 洛谷 P2038 无线网络发射器选址 —— 二维树状数组
题目:https://www.luogu.org/problemnew/show/P2038 大水题暴露出我的愚蠢. 用二维树状数组,然而居然忘了它应该那样写,调了一个小时: 正方形可以超出外面,只要 ...
- 洛谷 P1972"[SDOI2009]HH的项链"(离线+树状数组 or 在线+主席树)
传送门 •题意 给你一个包含 n 个数的数组 $a$: 有 m 此操作,每次操作求区间 [l,r] 中不同数的个数: •题解(离线+树状数组) 以样例 $[1,2,3,4,3,5]$ 为例,求解区间 ...
- 模板—点分治A(容斥)(洛谷P2634 [国家集训队]聪聪可可)
洛谷P2634 [国家集训队]聪聪可可 静态点分治 一开始还以为要把分治树建出来……• 树的结构不发生改变,点权边权都不变,那么我们利用刚刚的思路,有两种具体的分治方法.• A:朴素做法,直接找重心, ...
- [洛谷P1527] [国家集训队]矩阵乘法
洛谷题目链接:[国家集训队]矩阵乘法 题目背景 原 <补丁VS错误>请前往P2761 题目描述 给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数. 输入输出格式 输入 ...
- 洛谷 P2757 [国家集训队]等差子序列 解题报告
P2757 [国家集训队]等差子序列 题目描述 给一个\(1\)到\(N\)的排列\(\{A_i\}\),询问是否存在 \[1 \le p_1<p_2<p_3<p_4<p_5& ...
- 洛谷 P1527 [国家集训队]矩阵乘法 解题报告
P1527 [国家集训队]矩阵乘法 题目描述 给你一个\(N*N\)的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第\(K\)小数. 输入输出格式 输入格式: 第一行两个数\(N,Q\),表示矩阵大 ...
- BZOJ 2141 排队 (三维偏序CDQ+树状数组)
题目大意:略 洛谷传送门 和 [CQOI2015]动态逆序对 这道题一样的思路 一开始的序列视为$n$次插入操作 把每次交换操作看成四次操作,删除$x$,删除$y$,加入$x$,加入$y$ 把每次操作 ...
- Bzoj 2141: 排队 分块,逆序对,树状数组
2141: 排队 Time Limit: 4 Sec Memory Limit: 259 MBSubmit: 1310 Solved: 517[Submit][Status][Discuss] D ...
- 洛谷 1775. [国家集训队2010]小Z的袜子
1775. [国家集训队2010]小Z的袜子 ★★★ 输入文件:hose.in 输出文件:hose.out 简单对比时间限制:1 s 内存限制:512 MB [题目描述] 作为一个生活 ...
随机推荐
- Shtter抓图时,包含光标的解决方案
1.方案一,不用双击进行截图,用Enter. 2.进行配置.
- 配置mybatis-config.xml出现过很诡异的现象
1 首先得保证包的导入正确 2 然后如果把mybatis-config.xml放在src的某个文件夹下,最后能够build path 3 之后一直报 Archive for required libr ...
- 新东方雅思词汇---8.1、reckon
新东方雅思词汇---8.1.reckon 一.总结 一句话总结:reck(注意,留心)+on 英 ['rek(ə)n] 美 ['rɛkən] vt. 测算,估计:认为:计算 vi. 估计:计算:猜 ...
- SSL和SSH的区别
SSL是一种国际标准的加密及身份认证通信协议,您用的浏览器就支持此协议.SSL(Secure Sockets Layer)最初是由美国Netscape公司研究出来的,后来成为了Internet网上安全 ...
- Django进阶Admin篇 - admin基本配置
django admin 是django自带的一个后台app,提供了后台的管理功能. 基础知识点: 一.认识ModelAdmin 管理界面的定制类,如需扩展特定的model界面,需要从该类继承 二.注 ...
- 解决:TypeError: object() takes no parameters
运行测试用例时发现以下报错 Ran 1 test in 22.505s FAILED (errors=1) Error Traceback (most recent call last): File ...
- vue项目中报常见错误
最近做项目,添加了less样式之后报错, 添加了如下样式: 报错如下图: 于是,就把相关的依赖也都安装了 以为这样会好使啦,后来发现原来是vue-style-loader的问题, 安装的vue-sty ...
- .html() .text() .val() 的区别
.html()用为读取和修改元素的HTML标签(包括其Html标签) .text()用来读取或修改元素的纯文本内容 (包括其后代元素) .val()用来读取或修改表单元素的value值.(只能用于表单 ...
- 【lightoj-1039】A Toy Company(BFS)
The toy company "Babies Toys" has hired you to help develop educational toys. The current ...
- js中的函参(arguments)
函参,顾名思义,就是函数的参数,一般我们的js函数这么写: function sum(a,b){ console.log(a+b); } 不难看出,这实现了两个数的相加,比如sum(1,2),打印结果 ...