整理的算法模板合集: ACM模板

点我看算法全家桶系列!!!

实际上是一个全新的精炼模板整合计划


题目链接

https://hydro.ac/d/bzoj/p/2141

是 hydro 的 BZOJ 修复工程 !(我也去领了一点题慢慢修着玩,这题就是我修的嘿嘿嘿)

题目描述

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

红星幼儿园的小朋友们排起了长长地队伍,准备吃果果。不过因为小朋友们的身高有所区别,排成的队伍高低错乱,极不美观。设第 iii 个小朋友的身高为 hih_ihi​ 。

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

输入格式

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

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

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

以下 mmm 行每行包含两个正整数 aia_iai​ 和 bib_ibi​ ,表示交换位置 aia_iai​ 与位置 bib_ibi​ 的小朋友。

输出格式

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

输入样例

3
130 150 140
2
2 3
1 3

输出样例

1
0
3

数据规模和约定

对于 100%100\%100% 的数据,1≤m≤2×1031\le m\le 2\times 10^31≤m≤2×103,1≤n≤2×1041\le n\le 2\times 10^41≤n≤2×104,1≤hi≤1091\le h_i\le 10^91≤hi​≤109,ai≠bia_i\neq b_iai​​=bi​,1≤ai,bi≤n1\le a_i,b_i\le n1≤ai​,bi​≤n。

提示

【样例说明】

未进行任何操作时,(2,3)(2,3)(2,3) 为逆序对;

操作 111 结束后,序列为 130140150130\ 140\ 150130 140 150,不存在逆序对;

操作 222 结束后,序列为 150140130150\ 140\ 130150 140 130,(1,2)(1,2)(1,2),(1,3)(1,3)(1,3),(2,3)(2,3)(2,3) 共 333 对逆序对。

Solution

我们先对原序列使用树状数组求一次逆序对,然后考虑修改操作直接在原答案上进行更新维护答案。

考虑每次交换元素 ala_lal​ 与 ara_rar​ 时对答案的影响。

逆序对实际上是就是下标小于自己的元素中权值大于自己的数的个数,显然交换 l,rl,rl,r 之后,al,ara_l,a_ral​,ar​ 与区间 [1,l)[1,l)[1,l)、(r,n](r,n](r,n] 中的元素相对关系保持不变,答案无影响。

考虑交换操作对区间 (l,r)(l,r)(l,r) 内元素 aia_iai​ 的逆序对造成的影响

  • ai>al→ans+1a_i>a_l\rightarrow ans+1ai​>al​→ans+1

  • ai<al→ans−1a_i<a_l\rightarrow ans-1ai​<al​→ans−1

  • ai>ar→ans−1a_i>a_r\rightarrow ans-1ai​>ar​→ans−1

  • ai<ar→ans+1a_i<a_r\rightarrow ans+1ai​<ar​→ans+1

  • al>ar→ans−1a_l>a_r\rightarrow ans-1al​>ar​→ans−1

  • al<ar→ans+1a_l<a_r\rightarrow ans+1al​<ar​→ans+1

我们在使用树状数组计算逆序对的时候由于一维树状数组只有 val&cnt\mathrm{val}\ \&\ \mathrm{cnt}val & cnt ,仅维护序列前缀和, 并没有序列下标顺序这一维度,所以需要我们倒序循环来保证 j<ij<ij<i 这一条件。我们这里动态维护的时候,考虑涉及到的需要修改的区间 (l,r)(l,r)(l,r),并人为地维护顺序这一信息保证满足逆序对的条件 j<iANDaj>aij<i\ \mathrm{AND}\ a_j>a_ij<i AND aj​>ai​ 。我们可以使用平衡树来维护顺序这一维度,但是由于本题数据较小, n≤2×104n\le 2\times 10^4n≤2×104,考虑可以直接暴力分块。我们将序列分块,然后在每一个块内离散化后建一个树状数组 val&cnt\mathrm{val}\ \&\ \mathrm{cnt}val & cnt 维护小于自己的数的个数。分块维护序列,在区间 [l+1,r−1][l+1,r-1][l+1,r−1] 内的整块,我们每次直接 O(log⁡n)O(\log n)O(logn) 查询满足上述条件的 aia_iai​ 个数然后维护答案。对于区间 [l+1,r−1][l+1,r-1][l+1,r−1] 内的碎块,我们暴力循环维护答案。最后若 l,rl,rl,r 不在同一个块内,交换 al,ara_l,a_ral​,ar​ 之后需要对这两块的树状数组进行修改。

时间复杂度:O(nnlog⁡n)O(n\sqrt n\log \sqrt n)O(nn​logn​)

Code

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define lowbit(x) (x & (-x))
const int maxn = 2e4 + 7, maxb = 200 + 7;template<typename T> inline void read(T &x)
{int f = 0;char c = getchar();x = 0;while(!isdigit(c)) f |= c == '-', c = getchar();while(isdigit(c)) x = x * 10 + c - 48, c = getchar();if(f) x = -x;
}template<typename T > void print(T x)
{if(x < 0) putchar('-');if(x > 9) print(x / 10);putchar(x % 10 + 48);
}int n, m, s, t, ans;
int tr[maxb][maxn];
int a[maxn], b[maxn];
int block;
int belong[maxn];void modify(int p, int x, int v)
{for (; x <= maxn; x += lowbit(x))    tr[p][x] += v;
}int query(int p, int x)
{int res = 0;for (; x; x -= lowbit(x))res += tr[p][x];return res;
}int main()
{read(n);block = sqrt(n);for (int i = 1; i <= n; ++ i)read(a[i]), b[i] = a[i];sort (b + 1, b + 1 + n);int cnt = unique(b + 1, b + 1 + n) - b - 1;for (int i = 1; i <= n; ++ i)a[i] = lower_bound(b + 1, b + 1 + cnt, a[i]) - b;for (int i = 1; i <= n; ++ i) belong[i] = (i - 1) / block + 1;ans = 0;for (int i = n; i >= 1; -- i) {ans += query(0, a[i] - 1);modify(0, a[i], 1);}print(ans);puts("");for (int i = 1; i <= n; ++ i)modify(belong[i], a[i], 1);read(m);while(m -- ) {int L, R, l, r;read(l), read(r); if(l > r) swap(l, r);L = l + 1, R = r - 1;if(L <= R) { for (int i = L; i <= min(belong[L] * block, R); ++ i) {ans += (a[i] > a[l]);ans -= (a[i] < a[l]);ans -= (a[i] > a[r]);ans += (a[i] < a[r]);}    if(belong[L] != belong[R]) {for (int i = (belong[R] - 1) * block + 1; i <= R; ++ i) {ans += (a[i] > a[l]);ans -= (a[i] < a[l]);ans -= (a[i] > a[r]);ans += (a[i] < a[r]);}}for (int i = belong[L] + 1; i <= belong[R] - 1; ++ i) {ans += query(i, m) - query(i, a[l]);ans -= query(i, a[l] - 1);ans -= query(i, m) - query(i, a[r]);ans += query(i, a[r] - 1);}}ans -= (a[l] > a[r]);ans += (a[l] < a[r]);if(belong[l] != belong[r]) {modify(belong[l], a[l], -1);modify(belong[l], a[r], 1);modify(belong[r], a[l], 1);modify(belong[r], a[r], -1);}swap(a[l], a[r]);print(ans);puts("");}return 0;
}

BZOJ 2141 排队(块套树,分块,树状数组)【BZOJ修复工程】相关推荐

  1. bzoj 4765: 普通计算姬(分块+树状数组)

    4765: 普通计算姬 Time Limit: 30 Sec  Memory Limit: 256 MB Submit: 1481  Solved: 318 [Submit][Status][Disc ...

  2. bzoj 2141 : 排队 (cdq分治+bit)

    链接: https://www.lydsy.com/JudgeOnline/problem.php?id=2141 思路: 其实就是求动态逆序对...cdq降维,用树状数组前后求两遍逆序对就好了 切水 ...

  3. [cdq分治][树状数组] Bzoj P3262 陌上花开

    Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),用三个整数表示. 现在要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量. 定义一朵花A比另一朵花B要美 ...

  4. 二维树状数组 BZOJ 1452 [JSOI2009]Count

    题目链接 裸二维树状数组 #include <bits/stdc++.h>const int N = 305; struct BIT_2D {int c[105][N][N], n, m; ...

  5. [乱搞 树状数组] BZOJ 4548 小奇的糖果 BZOJ 3658 Jabberwocky

    跟悬线法有点像 #include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring ...

  6. BZOJ.4553.[HEOI2016TJOI2016]序列(DP 树状数组套线段树/二维线段树(MLE) 动态开点)

    题目链接:BZOJ 洛谷 \(O(n^2)\)DP很好写,对于当前的i从之前满足条件的j中选一个最大值,\(dp[i]=d[j]+1\) for(int j=1; j<i; ++j)if(a[j ...

  7. 【BZOJ】3052: [wc2013]糖果公园 树分块+带修改莫队算法

    [题目]#58. [WC2013]糖果公园 [题意]给定n个点的树,m种糖果,每个点有糖果ci.给定n个数wi和m个数vi,第i颗糖果第j次品尝的价值是v(i)*w(j).q次询问一条链上每个点价值的 ...

  8. 【BZOJ】1901: Zju2112 Dynamic Rankings(区间第k小+树状数组套主席树)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1901 首先还是吐槽时间,我在zoj交无限tle啊!!!!!!!!我一直以为是程序错了啊啊啊啊啊啊. ...

  9. 树套树 ----- P1975 [国家集训队]排队(树状数组套权值线段树求动态逆序对)

    解题思路: 首先我们知道交换两个数a[l]和a[r]a[l]和a[r]a[l]和a[r]影响到的区间是[l+1,r−1][l+1,r-1][l+1,r−1] 对于a[l]a[l]a[l],我们要减去[ ...

最新文章

  1. 传智播客视频学习 ---- 字符串含义( C 语言中)
  2. 精读《setState 做了什么》
  3. 剑指Offer04. 二维数组中的查找
  4. 用多媒体库 Bass.dll 播放 mp3 [9] - 绘制波形图
  5. editor.md 实现拖拽剪切复制粘贴上传图片,文件插件
  6. mysql主从安装_MySQL主从详细安装步骤
  7. javascript Arrow functions(箭头函数)
  8. [论文阅读] Transformer Transforms Salient Object Detection and Camouflaged Object Detection
  9. python可以做科学计算吗_用 Python 做科学计算之最小二乘
  10. python数据挖掘系列教程——PySpider框架应用全解
  11. 30岁菜鸟涛学习VB.net 第十三天
  12. datagrid 表格数据填充方式
  13. Kronecker 定理
  14. gre红宝书词汇量是多少?考试够用吗?
  15. iOS开发之打包上传到App Store——(一)各种证书的理解
  16. 深入学习区块链的隐私保护(四)秘密共享
  17. 蓝本(blueprint)
  18. 计算机二级考试vb内容,计算机二级VB考试内容大纲
  19. mysql 交换 表分区_mysql分区表分区数据和普通表交换
  20. android 支持最低版本是多少g,手机需要多少G的运行内存,才真正够用?

热门文章

  1. 如何让黑白图片恢复“生机”
  2. 机器学习库Scikit-learn库使用总结.pptx
  3. Leetode算法刷题宝典.pdf
  4. 链表问题16——单链表的选择排序
  5. Python logging调用Logger.info方法的处理过程
  6. 如何对DevOps数据库进行源代码控制
  7. ListBox滚动条置底
  8. python 易错总结
  9. Unity3D是怎么提升游戏运行效率的?
  10. SQL Server实用操作小技巧集合