博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
洛谷 P1975 [国家集训队]排队 Lebal:块内排序+树状数组
阅读量:7140 次
发布时间:2019-06-28

本文共 3942 字,大约阅读时间需要 13 分钟。

题目描述

排排坐,吃果果,生果甜嗦嗦,大家笑呵呵。你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家乐和和。

红星幼儿园的小朋友们排起了长长地队伍,准备吃果果。不过因为小朋友们的身高有所区别,排成的队伍高低错乱,极不美观。设第i个小朋友的身高为hi,我们定义一个序列的杂乱程度为:满足i<j且hi>hj的(i,j)数量。

幼儿园阿姨每次会选出两个小朋友,交换他们的位置,请你帮忙计算出每次交换后,序列的杂乱程度。为方便幼儿园阿姨统计,在未进行任何交换操作时,你也应该输出该序列的杂乱程度。

输入输出格式

输入格式:

 

第一行为一个正整数n,表示小朋友的数量;

第二行包含n个由空格分隔的正整数h1,h2,…,hn,依次表示初始队列中小朋友的身高;

第三行为一个正整数m,表示交换操作的次数;

以下m行每行包含两个正整数ai和bi­,表示交换位置ai与位置bi的小朋友。

 

输出格式:

 

输出文件共m+1行,第i行一个正整数表示交换操作i结束后,序列的杂乱程度。

 

输入输出样例

输入样例#1:
 
3130 150 14022 31 3
输出样例#1:
 
103

说明

【样例说明】

未进行任何操作时,(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,m15 ;

对于30%的数据, n,m \le 200n,m200 ;

在剩下的70%数据中:

存在15%的数据, h_ihi 各不相同;

存在15%的数据, 1^{10} \le h_i \le 1^{60}110hi160 ;

以上两类数据不存在交集。

对于100%的数据, 1 \le m \le 2\times 10^31m2×103 , 1 \le n \le 2 \times 10^41n2×104 , 1 \le h_i \le 10^91hi109 , a_i \ne b_iaibi , 1 \le a_i,b_i \le n1ai,bin。

代码

直接暴力分块,然后在每一个块内排序。

查询时可以在每一个块内二分。

#include 
#include
#include
#include
#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;}

  

转载于:https://www.cnblogs.com/radiumlrb/p/9394001.html

你可能感兴趣的文章
centos7.4之zabbix4.0的fping监控
查看>>
python基础知识 ~ 函数补充与反射
查看>>
xss攻击
查看>>
[CC-ANUCBC]Cards, bags and coins
查看>>
Riemann-Stieltjes积分存在的充分条件(按照Tom M.Apostol的《数学分析》上的定义)
查看>>
ahjesus —— javascript命名规范1.10
查看>>
caller 和 callee的对比
查看>>
使用GDB调试gp(转载)
查看>>
用Python给你的博客加上水印
查看>>
线性微分方程与常数变异法
查看>>
选夫婿1 结构体
查看>>
算法之折半查找
查看>>
webpack实用小功能介绍
查看>>
OpenStack high-level Functionsenabled
查看>>
深入理解Linux内核-内核同步
查看>>
zabbix实现mysql数据库的监控(三)
查看>>
外观模式-多了个办事处
查看>>
laravel 文件上传
查看>>
《寻路算法第二篇》A*寻路的路径平滑、静态合并、生成格子工具自动化、
查看>>
求职防骗指南
查看>>