UVA 11990 ``Dynamic'' Inversion (序列分治)
26天以前做过的一道题,之前的做法是分治预处理,树套树在线修改,复杂度为O(nlogn+m*logn*logn),代码量较大。
本来想学习一下cdq分治的,看到论文上的凸包、斜率就暂时放一边了,只知道和一般的分治的不同是左子问题可以用来解决右边的子问题。
今天下午YY了一个离线的分治做法,也不知道叫不叫cdq。
Analysis:
对于每一个数字,构成逆序对除了val大小还和被删除的时间del有关,这实际上是一个三维偏序的问题。
一个元素是一个三元组e(pos,val,del),e1和e2对答案有贡献当且仅当e1.pos < e1.pos && e1.val > e2.val && e1.del > e2.del。
第一维pos已经给好了,第二个维度就用归并,而第三个维度就用树状数组(BIT)。用BIT的想法来源于,BIT插入的顺序对应着之前都
已经满足的序,在这里就是已经满足e1.pos < e1.pos && e1.val > e2.val ,然后用del查询作为下标就可以查询到满足第三个条件e1.del > e2.del的元素个数。
Note:
思想如此,实现上有还值得注意的地方,一是BIT插入的值域范围不能太大,所以我记录了两个关于时间的信息tKth[],tRank[],
tKth[i]表示当前区间第i大的del,tRank[del]表示del在当前区间的名次,(名次从1开始,0表示没有删去),可以很方便地用归并去维护。
二是BIT只能查询小的,需要转化。总对数是容易得到的,用总对数去减就好了。
BIT需要事先知道值域范围,这题只有删除,如果带有修改则应该改成平衡树。
复杂度
依然是O(nlogn+m*logn*logn),但常数很小,代码量也比较小。

#include<bits/stdc++.h>
using namespace std; typedef long long ll; const int maxn = 2e5+, maxm = 1e5+;
ll ans;
int iv_pir[maxn], a[maxn], tRank[maxn], tKth[maxn];
int del[maxn], temp[maxn];
int C[][maxn];
int qry[maxm]; #define lb(x) (x&-x)
void add(int C[],int x,int d,int range)
{
//if(x<1) return;
while(x <= range){
C[x] += d; x += lb(x);
}
} int sum(int C[],int x)
{
int re = ;
while(x>){
re += C[x]; x -= lb(x);
}
return re;
} void divide(int l,int r)
{
if(l == r) {
if(del[a[l]]) {
tKth[l] = del[a[l]];
}
return;
}
int mid = (l+r)>>;
divide(l, mid);
divide(mid+, r);
//conquer int p = l, q = mid+, k = ;
while(p <= mid && !tKth[p]) { temp[k++] = ; p++; }
while(q <= r && !tKth[q]) { temp[k++] = ; q++; }
int base = l+k-;
while(p<=mid || q<=r){
if(p>mid || (q<=r && tKth[p] > tKth[q])) {
temp[k++] = tKth[q++];
}else {
temp[k++] = tKth[p++];
}
}
memcpy(tKth+l,temp,sizeof(int)*k);
for(int i = base+; i <= r; i++){
tRank[tKth[i]] = i-base;
}
int sz = r-base;
memset(C[]+,,sizeof(int)*(sz));
memset(C[]+,,sizeof(int)*(sz));
for(int i = l; i <= mid; i++) {
if(del[a[i]])
add(C[],tRank[del[a[i]]],,sz);
} p = l, q = mid+, k = ;
while(p<=mid || q<=r){
if(p>mid || (q<=r && a[p] > a[q])) {
ans += mid-p+;
if(del[a[q]]){
iv_pir[a[q]] += mid-p+ - sum(C[], tRank[del[a[q]]]);
add(C[], tRank[del[a[q]]], , sz);
}
temp[k++] = a[q++];
}else {
if(del[a[p]]){
iv_pir[a[p]] += q-mid- - sum(C[], tRank[del[a[p]]]);
add(C[], tRank[del[a[p]]], -, sz);
}
temp[k++] = a[p++];
}
}
memcpy(a+l, temp, sizeof(int)*k);
} //#define LOCAL
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
#endif
int n, m; ;
while(~scanf("%d%d", &n, &m)){
for(int i = ; i < n; i++) scanf("%d", a+i);
memset(del+,,sizeof(int)*n);
for(int i = ; i <= m; i++) {
scanf("%d", qry+i);
del[qry[i]] = i;
iv_pir[qry[i]] = ;
}
ans = ;
divide(,n-);
for(int i = ; i <= m; i++){
printf("%lld\n", ans);
ans -= iv_pir[qry[i]];
}
}
return ;
}
UVA 11990 ``Dynamic'' Inversion (序列分治)的更多相关文章
- UVA 11990 `Dynamic'' Inversion CDQ分治, 归并排序, 树状数组, 尺取法, 三偏序统计 难度: 2
题目 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&a ...
- UVA 11990 ``Dynamic'' Inversion 动态逆序对
``Dynamic'' Inversion Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 https://uva.onlinejudge.org/index ...
- UVA 11990 ``Dynamic'' Inversion (线段树套BIT,分治)
题目要求可转化为查询一个区间内有多少数比val大(或者小). 区间用线段树分解(logN),每个区间维护一rank树. rank可用BIT查询,往BIT里面插值,为了保证不同区间的BIT互不影响要先离 ...
- UVA 11990 ”Dynamic“ Inversion(线段树+树状数组)
[题目链接] UVA11990 [题目大意] 给出一个数列,每次删去一个数,求一个数删去之前整个数列的逆序对数. [题解] 一开始可以用树状数组统计出现的逆序对数量 对于每个删去的数,我们可以用线段树 ...
- [CF888E] Maximum Subsequence 序列分治
早期作品,不喜轻喷. LG传送门 序列分治板子题. 切这道题用了好长时间,所以想发篇题解作为纪念 . 首先,我们认真观察题目数据(面向数据做题是个好习惯),发现题目的\(n\)竟然只有\(35\),我 ...
- 算法复习——序列分治(ssoj光荣的梦想)
题目: 题目描述 Prince对他在这片大陆上维护的秩序感到满意,于是决定启程离开艾泽拉斯.在他动身之前,Prince决定赋予King_Bette最强大的能量以守护世界.保卫这里的平衡与和谐.在那个时 ...
- UVA - 1625 Color Length[序列DP 代价计算技巧]
UVA - 1625 Color Length 白书 很明显f[i][j]表示第一个取到i第二个取到j的代价 问题在于代价的计算,并不知道每种颜色的开始和结束 和模拟赛那道环形DP很想,计算这 ...
- Uva 3767 Dynamic len(set(a[L:R])) 树套树
Dynamic len(set(a[L:R])) Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 https://uva.onlinejudge.org/in ...
- UVA - 1625 Color Length[序列DP 提前计算代价]
UVA - 1625 Color Length 白书 很明显f[i][j]表示第一个取到i第二个取到j的代价 问题在于代价的计算,并不知道每种颜色的开始和结束 和模拟赛那道环形DP很想,计算这 ...
随机推荐
- [CentOS7] 设备与文件名对应表
- UML——初识
初识 刚刚接触到UML的时候,先看的书,对整本书的内容做了宏观的把控.感觉UML这个东西和自己想象中的不一样.起初我认为它只是一个工具,将软件开发过程中不同的阶段用不用种类的图表现出来,后来才发现它是 ...
- thinkphp5引入百度编辑器
在ThinkPHP的模板(html文件)中引入Ueditor 下载ueditor解压至public/static目录 在需要的页面引入js文件 <script type="text/ ...
- DHCPv6协议
DHCPv6协议 1. 定义 IPv6 动态主机配置协议DHCPv6(Dynamic Host Configuration Protocol for IPv6)是针对IPv6编址方案设计,为主 ...
- DozerBeanMapper 配置
applicationContext.xml <bean id="mapper" class="org.dozer.spring.DozerBeanMapperFa ...
- (转)vimdiff 快速比较和合并少量文件
vimdiff 快速比较和合并少量文件 原文:http://www.cnblogs.com/abeen/p/4255754.html 纯文本文件比较和合并工具一直是软件开发过程中比较重要的组成部分,v ...
- Java安装JDBC驱动教程(SQL Server系列)
端口一般开放都没问题,默认设置就行,第一步下载JDBC,我自己在使用微软新的JDBC6.0的包的时候出错,后来就退回到JDBC4.0引用,完美使用. SQLJDBC4.0下载地址:点击下载 下载之后, ...
- MySQL导入大sql 文件大小限制问题的解决
解决过程如下: 1.由于mysql能解析sql的压缩文件,因此将200M压缩后为5M. 2.默认情况下:MySQL导入文件大小有限制的,最大为2M,所以当文件很大时候,直接无法导入,可修改php.in ...
- 打印机设置dns
1.登录打印机网页:打印机的ip 2.点击网络--网络标识--设置DNS
- VMware 虚拟机安装及部署
Linux系统安装及网络配置 这篇文章介绍关于Linux系统的安装以及网络配置,关于虚拟机配置中网络的几个模式区别进行详细讲解.学习Linux对于后端开发人员来说是很有必要的,结合实际开发,Linux ...