【BZOJ3295】【块状链表+树状数组】动态逆序对
Description
Input
Output
Sample Input
1
5
3
4
2
5
1
4
2
Sample Output
2
2
1
样例解释
(1,5,3,4,2)(1,3,4,2)(3,4,2)(3,2)(3)。
HINT
N<=100000 M<=50000
【分析】
这种水题还弄了两节课...真是没法治了。
用很多种方法,最好理解的就是块状链表套树状数组,每个块状链表里面套一个二维的树状数组,再加上离散化。
将m序列中的每一个数字对应一个坐标(在n中坐标,n-数字大小)然后就可以做了。
我还开了3个一维树状数组,卡着时间过的。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <utility>
#include <iomanip>
#include <string>
#include <cmath>
#include <queue>
#include <assert.h>
#include <map> const int N = + ;
const int SIZE = ;//块状链表的根号50000
const int M = + ;
using namespace std;
typedef long long ll;
int lowbit(int x) {return x & -x;}
struct BLOCK_LIST{
int C[SIZE][SIZE];
int t[][SIZE];//关于a的离散化序列和b的离散化序列
void init(){
memset(C, , sizeof(C));
memset(t, , sizeof(t));
}
int sum(int x, int y){
int cnt = , f = y;
//int flag = x;
while (x > ){
while (y > ){
cnt += C[x][y];
y -= lowbit(y);
}
x -= lowbit(x);
y = f;
}
return cnt;
}
void add(int x, int y){
int f = y;
while (x < SIZE){
while (y < SIZE){
C[x][y]++;
y += lowbit(y);
}
x += lowbit(x);
y = f;
}
return;
}
//二分搜索,查找x在k内相当的值
int search(int k, int x){
int l = , r = , Ans;
while (l <= r){
int mid = (l + r) >> ;
if (t[k][mid] <= x) Ans = mid, l = mid + ;
else r = mid - ;
}
return Ans;
}
}list[SIZE];
struct DATA{
int t[];//影响m的树状数组的两个值,注意都要进行离散化
int x;//值
}rem[M];
struct LSH{
int num, order;
bool operator < (LSH b)const{
return num < b.num;//专门用来离散化
}
}A[M];
int data[N], c[][N], n, m;
int num[N];//num[N]代表i有i存在的逆序对的个数
ll tot;//记录逆序对的个数 ll sum(int k, int x){
ll cnt = ;
while (x > ){
cnt += c[k][x];
x -= lowbit(x);
}
return cnt;//记得要用ll
}
void add(int k, int x){
while (x <= n){
c[k][x]++;
x += lowbit(x);
}
return;
}
void init(){
tot = ;
memset(num, , sizeof(num));
memset(c, , sizeof(c));
scanf("%d%d", &n, &m);
for (int i = ; i <= n; i++){
int x;
scanf("%d", &x);
data[x] = i;
int tmp = sum(, x);
num[x] += (i - - tmp);//先求出在i之前的比i大的数
num[x] += (x - tmp - );//后面比i小的数
tot += (i - - tmp);
add(, x);
}
//printf("%d\n", tot);
//for (int i = 1; i <= n; i++) printf("%d\n", num[i]);
}
//离散化
void prepare(){
//a,b中两个值分别为位置和大小
for (int i = ; i <= m; i++){
int tmp;
scanf("%d", &tmp);
rem[i].t[] = data[tmp];
rem[i].t[] = n - tmp + ;
rem[i].x = tmp;
}
//for (int i = 1; i <= m; i++) printf("%d %d %d\n", rem[i].t[0], rem[i].t[1], rem[i].x);
}
void get(int k, int l, int r, int x){
int cnt = r - l + , pos = ;
for (int i = l; i <= r; i++){
A[pos].order = i;
A[pos].num = rem[i].t[k];
pos++;
}
sort(A + , A + cnt + );
for (int i = ;i <= cnt; i++) list[x].t[k][i] = A[i].num;
for (int i = ;i <= cnt; i++) rem[A[i].order].t[k] = i;
}
void work(){
for (int i = ; i < SIZE; i++) list[i].init();
int cnt = ;//cnt是用来记录块的数量
for (int pos = ; pos <= m; pos++){ int l = pos;
l = min(m , + pos - );
//从[l,m]这一段放在list[cnt]里面
get(, pos, l, cnt);
get(, pos, l, cnt);
for (int i = pos; i <= l; i++){
printf("%lld\n", tot);
int tmp = list[cnt].sum(rem[i].t[], rem[i].t[]);
for (int j = ; j < cnt; j++) tmp += list[j].sum(list[j].search(, list[cnt].t[][rem[i].t[]]), list[j].search(, list[cnt].t[][rem[i].t[]])); tot -= (num[rem[i].x] - (tmp + (sum(, rem[i].x) - (sum(, list[cnt].t[][rem[i].t[]]) - tmp))));
list[cnt].add(rem[i].t[], rem[i].t[]);
add(, list[cnt].t[][rem[i].t[]]);
add(, rem[i].x);
}
cnt++;
pos = l;
}
} int main(){
#ifdef LOCAL
freopen("data.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
init();
prepare();
if (m == ) return ;
else work();
return ;
}
【BZOJ3295】【块状链表+树状数组】动态逆序对的更多相关文章
- POJ2299Ultra-QuickSort(归并排序 + 树状数组求逆序对)
树状数组求逆序对 转载http://www.cnblogs.com/shenshuyang/archive/2012/07/14/2591859.html 转载: 树状数组,具体的说是 离散化+树 ...
- poj3067 Japan 树状数组求逆序对
题目链接:http://poj.org/problem?id=3067 题目就是让我们求连线后交点的个数 很容易想到将左端点从小到大排序,如果左端点相同则右端点从小到大排序 那么答案即为逆序对的个数 ...
- SGU180(树状数组,逆序对,离散)
Inversions time limit per test: 0.25 sec. memory limit per test: 4096 KB input: standard output: sta ...
- [NOIP2013提高&洛谷P1966]火柴排队 题解(树状数组求逆序对)
[NOIP2013提高&洛谷P1966]火柴排队 Description 涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度. 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相 ...
- [NOI导刊2010提高&洛谷P1774]最接近神的人 题解(树状数组求逆序对)
[NOI导刊2010提高&洛谷P1774]最接近神的人 Description 破解了符文之语,小FF开启了通往地下的道路.当他走到最底层时,发现正前方有一扇巨石门,门上雕刻着一幅古代人进行某 ...
- 【bzoj2789】[Poi2012]Letters 树状数组求逆序对
题目描述 给出两个长度相同且由大写英文字母组成的字符串A.B,保证A和B中每种字母出现的次数相同. 现在每次可以交换A中相邻两个字符,求最少需要交换多少次可以使得A变成B. 输入 第一行一个正整数n ...
- poj3067Japan——树状数组查找逆序对
题目:http://poj.org/problem?id=3067 利用树状数组查找逆序对. 代码如下: #include<iostream> #include<cstdio> ...
- “浪潮杯”第九届山东省ACM大学生程序设计竞赛(重现赛)E.sequence(树状数组求逆序对(划掉))
传送门 E.sequence •题意 定义序列 p 中的 "good",只要 i 之前存在 pj < pi,那么,pi就是 "good": 求删除一个数, ...
- 2021.12.10 P5041 [HAOI2009]求回文串(树状数组求逆序对)
2021.12.10 P5041 [HAOI2009]求回文串(树状数组求逆序对) https://www.luogu.com.cn/problem/P5041 题意: 给一个字符串 \(S\) ,每 ...
- NOIP 2013 洛谷P1966 火柴排队 (树状数组求逆序对)
对于a[],b[]两个数组,我们应选取其中一个为基准,再运用树状数组求逆序对的方法就行了. 大佬博客:https://www.cnblogs.com/luckyblock/p/11482130.htm ...
随机推荐
- google font和@font-face
会使用google字体 网址: http://www.google.com/fonts/ 选择字体, quick use 引用css: <link href='http://fonts.goog ...
- Unity3d 超级采样抗锯齿 Super Sampling Anti-Aliasing
Super Sampling Anti-AliasingSSAA算是在众多抗锯齿算法中比较昂贵的一种了,年代也比较久远,但是方法比较简单,主要概括为两步1. 查找边缘2. 模糊边缘这是一种 ...
- STM32F072B-DISCO 深入研究 USB系统
调试USB例题需要用到2个上位机程序: PC端HID交互程序,提供了VC源程序. 图形方式的按钮输入.LED输出操作: 总线扑捉器: main程序初始化部分很简单: /* Initialize USB ...
- 将cocos的app直接在我的设备上测试运行
首先,你要有一个写好了的,准备在真机上测试的cocos程序. 1.设置ARC,设置的过程在另外一篇博文上有写. 2.在Target的Build Setting里面 找到Valid Archs 删除里面 ...
- 《图解密码技术》-chaper1-概述
密码和信息安全常识: (1)不要使用保密的密码算法. (2)不要使用低强度密码算法. (3)密码一定会被破解. (4)密码只是信息安全的一部分.
- Django中的CSRF
CSRF(Cross Site Request Forgery, 跨站域请求伪造) CSRF 背景与介绍 CSRF(Cross Site Request Forgery, 跨站域请求伪造)是一种网络的 ...
- js实现table中前端搜索(模糊查询)
项目中用到js前端搜索功能,根据 姓名或姓名 进行 搜索,实现方法如下,遍历table所有行中的某列,符合条件则置tr为display:'',不满足条件置tr为display:none. 代码如下: ...
- 设计模式(4) -- 单例模式(Singleton)
设计模式(4) -- 单例模式(Singleton) 试想一个读取配置文件的需求,创建完读取类后通过New一个类的实例来读取配置文件的内容,在系统运行期间,系统中会存在很多个该类的实例对象,也就是说 ...
- 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(21)-权限管理系统-跑通整个系统
原文:构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(21)-权限管理系统-跑通整个系统 这一节我们来跑通整个系统,验证的流程,通过AOP切入方式,在访问方法之 ...
- HP P2055d激光打印机PCL XL error的解决
近日,于客户处安装HP P2055d激光打印机(2009年11月份生产的机器),介绍下硬件环境:PC:Dell OptiPlex 360,另有一台富士通DPK 8600E票据打印机,P2055d通过U ...