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很想,计算这 ...
随机推荐
- Maven核心知识
什么是Maven? Maven是基于项目对象模型(POM), 可以通过一小段描述信息来管理项目的构建和文档的软件项目管理工具 目录结构如下 src main java package test jav ...
- Educational Codeforces Round 52F(树形DP,VECTOR)
#include<bits/stdc++.h>using namespace std;int n,k;vector<int>son[1000007];int dp[100000 ...
- ios开发 xcode6以上安装Alcatraz管理插件
在终端上输入如下命令即可完成安装: curl -fsSL https://raw.github.com/supermarin/Alcatraz/master/Scripts/install.sh | ...
- 自定义标签报 无法为TAG [my2:hello]加载标记处理程序类[null]
今天练习jsp自定义标签的时候,等我写好全部和检查万无一失的时候.执行然后报错了 无法为TAG [my2:hello]加载标记处理程序类[null] 我反复检查代码,发现代码也没什么问题.后面通过百度 ...
- spring boot 报错
错误1: 循环 的 请求. ..例如 cirle..url 在返回的模板路径上 加速 "/" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 错误2 : 添加了sh ...
- 牛客练习赛43D(贪心)
有生之年我居然也能不看题解做出来题QAQ-- 发现c.d是0.1序列而不是随机数列说明有蹊跷,于是发现负数直接配0,正数配1即可.不知道哪个最小,那就全求一下吧--我的做法的坑点是数正好为1时不可以选 ...
- myeclipse非正常关闭处理办法
myeclipse正常或非正常关闭后,再次运行,不显示启动时的logo和读条,进入主页面后程序基本就卡死,无法正常运行,解决办法. 方法一:修改工作空间在刚启动Myeclipse的时候会有一个选择工作 ...
- 021 Merge Two Sorted Lists 合并两个有序链表
Merge two sorted linked lists and return it as a new list. The new list should be made by splicing t ...
- java编程如何实现从本地里读取文件1,写入到本地另一个文件2里(多种场景)
不多说,直接上干货! 有时候,我们需要用到这样的一个场景. ReadLocalFile1WriteLocalFile2.java (以下是相当于复制,读取文件1里的全部内容,并写入到文件2里) pac ...
- 【Linux】ubuntu安装jdk-6u45-linux-x64.bin
for : Android4.4源码编译 环境 : ubuntu12.04_desktop_amd64 1. 1.1.jdk-6u45-linux-x64.bin 放置于 /home 1.2.命令&q ...