题目要求可转化为查询一个区间内有多少数比val大(或者小)。

区间用线段树分解(logN),每个区间维护一rank树。

rank可用BIT查询,往BIT里面插值,为了保证不同区间的BIT互不影响要先离散。

首先进行分治,分治的同时归并排序完成离散并计算保存出每个元素和其他元素构成的逆序对iv[i]。(据说这叫归并树

初始值将所有iv求和,一个对被算了两次所以除以二。

每次删除元素val就减去val对应的逆序对。

减去iv[val],但是多减去了和之前删掉元素构成的逆序对(这些逆序对已经算过一次)。

所以把删掉的元素加到线段树里面。

减去当前iv[val]之后,查询并加上当前元素val和之前位置以及之后位置构成逆序对。

复杂度

O(nlogn)预处理,O(m*logn*logn)回答

#include<bits/stdc++.h>
using namespace std; const int maxn = 2e5+, LogN = ; typedef long long ll;
ll invPair;
int a[maxn],p[maxn];
int iv[maxn];
int n; int s[maxn<<];
int C[LogN][maxn];
int Set[LogN][maxn]; #define para int o = 1, int l = 1,int r = n,int dep = 0
#define lo (o<<1)
#define ro (o<<1|1)
#define TEMP int mid = (l+r)>>1, lc = lo, rc = ro;
#define lsn lc, l, mid, dep+1
#define rsn rc, mid+1, r, dep+1 #define lb(x) ((x)&-(x))
int sum(int C[],int x)
{
int re = ;
while(x>){
re += C[x];
x -= lb(x);
}
return re;
} void add(int C[],int x,int d,int r)
{
while(x<=r){
C[x] += d;
x += lb(x);
}
} int qpos;
int ql,qr,val;
void queryPrefix(para)
{
if(<=l&&r<=qr){
int pos = upper_bound(Set[dep]+l,Set[dep]+r+,val)-Set[dep]-l;//等于等于val的最大元素的编号
invPair += s[o] - sum(C[dep]+l-,pos);//得到大于val的元素个数
}else {
TEMP
queryPrefix(lsn);
if(qr>mid) queryPrefix(rsn);
}
} void querySuffix(para)
{
if(ql<=l&&r<=n){
int pos = lower_bound(Set[dep]+l,Set[dep]+r+,val)-Set[dep]-l;//严格小于val的元素的编号
invPair += sum(C[dep]+l-,pos);
}else {
TEMP
if(ql<=mid) querySuffix(lsn);
querySuffix(rsn);
}
} void modify(para)
{
s[o]++;
if(l == r){
C[dep][l] = ;
}else{
TEMP
if(qpos<=mid) modify(lsn);
else modify(rsn);
int pos = upper_bound(Set[dep]+l,Set[dep]+r+,val)-Set[dep]-l;//val在set里,从1开始编号
add(C[dep]+l-,pos,,r-l+);//l-1是0号位,容纳r-l+1个元素
}
} //为保证BIT之间互不影响,merge_sort离散,同时计算逆序对
void discretize(para)
{
s[o] = ;
memset(C[dep]+l,,sizeof(int)*(r-l+));
if(l == r) {
Set[dep][l] = a[l];
return;
}else {
TEMP;
discretize(lsn);
discretize(rsn);
int p = l, q = mid+, k = l;
while(p<=mid || q<=r){
if(q > r|| (p <= mid && Set[dep+][p] <= Set[dep+][q]) ){
iv[Set[dep+][p]] += k-p;//和后面的数构成逆序对
Set[dep][k++] = Set[dep+][p++];
}else {
iv[Set[dep+][q]] += mid-p+;//和前面的数构成逆序对
Set[dep][k++] = Set[dep+][q++];
}
}
}
} //#define LOCAL
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
#endif
int m;
while(~scanf("%d%d",&n,&m)){
memset(iv+,,sizeof(int)*n);
for(int i = ; i <= n; i++){
scanf("%d",a+i);
p[a[i]] = i;
}
invPair = ;
discretize();
for(int i = ; i <= n; i++){
invPair += iv[i];
}
invPair >>= ;
while(m--){
scanf("%d",&val);
printf("%lld\n",invPair);
invPair -= iv[val];
qr = p[val]-;
ql = p[val]+;
if(qr>=) queryPrefix();
if(ql<=n) querySuffix();
qpos = p[val];
modify();
}
}
return ;
}

UVA 11990 ``Dynamic'' Inversion (线段树套BIT,分治)的更多相关文章

  1. UVA 11990 ”Dynamic“ Inversion(线段树+树状数组)

    [题目链接] UVA11990 [题目大意] 给出一个数列,每次删去一个数,求一个数删去之前整个数列的逆序对数. [题解] 一开始可以用树状数组统计出现的逆序对数量 对于每个删去的数,我们可以用线段树 ...

  2. UVA 11990 ``Dynamic'' Inversion 动态逆序对

    ``Dynamic'' Inversion Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 https://uva.onlinejudge.org/index ...

  3. uva 12003 Array Transformer (线段树套平衡树)

    http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&p ...

  4. BZOJ.1901.Dynamic Rankings(线段树套平衡树 Splay)

    题目链接or Here 题意:n个数,有两个操作:1.修改某个数为v:2.询问一段区间第k小的数 如果没有修改,则可以用线段树,每个节点P[a,b]存储大小为b-a+1的数组,代表其中的数 同时,这个 ...

  5. UVA 11990 ``Dynamic'' Inversion (序列分治)

    26天以前做过的一道题,之前的做法是分治预处理,树套树在线修改,复杂度为O(nlogn+m*logn*logn),代码量较大. 本来想学习一下cdq分治的,看到论文上的凸包.斜率就暂时放一边了,只知道 ...

  6. UVA 11990 `Dynamic'' Inversion CDQ分治, 归并排序, 树状数组, 尺取法, 三偏序统计 难度: 2

    题目 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&a ...

  7. [BZOJ 1901] Dynamic Rankings 【树状数组套线段树 || 线段树套线段树】

    题目链接:BZOJ - 1901 题目分析 树状数组套线段树或线段树套线段树都可以解决这道题. 第一层是区间,第二层是权值. 空间复杂度和时间复杂度均为 O(n log^2 n). 线段树比树状数组麻 ...

  8. BZOJ 1901: Zju2112 Dynamic Rankings 区间k大 带修改 在线 线段树套平衡树

    之前写线段树套splay数组版..写了6.2k..然后弃疗了.现在发现还是很水的..嘎嘎.. zju过不了,超时. upd:才发现zju是多组数据..TLE一版才发现.然后改了,MLE...手写内存池 ...

  9. 树套树Day1线段树套平衡树bzoj3196

    您需要写一种数据结构,来维护一个有序数列,其中需要提供以下操作:1.查询k在区间内的排名2.查询区间内排名为k的值3.修改某一位值上的数值4.查询k在区间内的前驱(前驱定义为小于x,且最大的数)5.查 ...

随机推荐

  1. CentOS7 搭建 rsync 服务器

    1:安装软件包: yum install -y rsync 2:修改配置文件: /etc/rsyncd.conf uid = root gid = root use chroot = yes #下面是 ...

  2. 微信小程序小结(2) ------ 自定义组件

    在小程序中有模板跟组件的概念.但模板更多的用于内容的展示,更复杂的交互逻辑就没办法了.所以在小程序中也定义了一些组件来解决一些简单逻辑的功能. 但有时预定义的组件并不能满足我们的需求,这时就需要我们自 ...

  3. 通过增删改查对比Array,Map,Set,Object的使用成本和实现方式

    1.Array 和 Map 对比 { // array and map 增 查 改 删 let map = new Map(); let arr = []; // 增 map.set('a', 1); ...

  4. Codeforces Round #558 (Div. 2)C(计算几何,排列组合,模拟)

    #include<bits/stdc++.h>using namespace std;typedef struct{ double k,b;}node;node k[1000007];bo ...

  5. 如何给自己的开源项目选择和添加 License

    License 的作用:开源 == 为所欲为? 开源并不等于为所欲为! 代码的用途,修改之后的代码有什么要求,开源程序对于原作者的权利和责任等等,都是需要明确的. 开源协议 License 就是这么一 ...

  6. Node.js 内置模块crypto使用事件方法(onreadable)加密的一些问题

    javaScript代码如下: 'use strict'; const crypto = require('crypto'); //实例化一个AES加密对象 const aesEncrept = cr ...

  7. 高效法则 之 你还在用这么low的方法打开软件吗?

    电脑上的诸多功能被组织成软件的形式提供给用户.聊天的有QQ/Skype,看电影的有腾讯视频/芒果TV,听音乐的有酷狗/LessDJ,做图的有PS/Sketch,写代码搞开发的各种IDE Eclipse ...

  8. A*算法的认识与求第K短路模板

    现在来了解A*算法是什么 现在来解决A*求K短路问题 在一个有权图中,从起点到终点最短的路径成为最短路,第2短的路成为次短路,第3短的路成为第3短路,依此类推,第k短的路成为第k短路.那么,第k短路怎 ...

  9. Linux--2 Linux之文档与目录结构、shell基本命令

    一.Linux之文档与目录结构 1.Linux之文档与目录结构 Linux目录结构的组织形式和Windows有很大的不同.Linux没有“盘(如C盘.D盘.E盘)”的概念,而是建立一个根"/ ...

  10. SpringBoot源码篇:深度分析SpringBoot如何省去web.xml

    一.前言 从本博文开始,正式开启Spring及SpringBoot源码分析之旅.这可能是一个漫长的过程,因为本人之前阅读源码都是很片面的,对Spring源码没有一个系统的认识.从本文开始我会持续更新, ...