题目大意是在能够改变两个数的位置的情况下计算逆序对数

这因为是动态记录逆序对

本来单纯逆序对只要用树状数组计算即可,但这里因为更新,所以利用TReap树的删点和增加点来进行更新

大致是把每个树状数组所管理的点都放在对应的Treap树下,

这样x-=lowbit(x)下来,正好访问到是所有比他小范围下的点了

然后根据每棵访问到的Treap树有多少个节点是比当前值小的即可

每次交换ai , aj , (i<j)只要考虑(i,j)范围内比ai大的数,比aj小的数,然后加加减减即可

如果ai!=aj也是要加减1

 #include <bits/stdc++.h>

 using namespace std;
#define N 20005 struct Node{
int l , r , val , sz , pri , cnt;
//cnt表示当前位置相同的数有多少个,pri表示优先级,sz表示这棵子树所含有的节点总个数
Node(){
l = r = ;
cnt = sz = , pri = rand();
val = ;
}
Node(int v){
Node();
val = v;
}
};
#define ls node[x].l
#define rs node[x].r
namespace Treap{
int tot;//Treap Node节点的总个数
int A[N];//有n棵treap树,A[]表示每棵treap树的起始位置
Node node[N*];
void init(){
node[] = Node();
node[].cnt = node[].sz = ;
memset(A , , sizeof(A));
tot = ;
}
int newNode(int v){
++tot;
node[tot].cnt = node[tot].sz = ;
node[tot].l = node[tot].r = ;
node[tot].pri = rand();
node[tot].val = v;
return tot;
}
void push_up(int x) {
// cout<<"here: "<<x<<" "<<ls<<" "<<rs<<endl;
if(x>)
node[x].sz = node[ls].sz+node[rs].sz+node[x].cnt;
}
void rotL(int &x){
int y = rs;
rs = node[y].l;
node[y].l = x; push_up(x);
push_up(y);
x = y;
}
void rotR(int &x){
int y = ls;
ls = node[y].r;
node[y].r = x; push_up(x);
push_up(y);
x = y;
}
void insert(int &x , int v){
// cout<<x<<" "<<v<<endl;
if(x == ) x = newNode(v);
else if(node[x].val>v){
insert(ls , v);
if(node[ls].pri>node[x].pri) rotR(x);
}
else if(node[x].val<v){
insert(rs , v);
if(node[rs].pri>node[x].pri) rotL(x);
}
else node[x].cnt++;
push_up(x);
// cout<<x<<" "<<v<<" "<<"endd"<<endl;
}
void erase(int &x , int v){
if(x == ) return ;
else if(v<node[x].val) erase(ls , v);
else if(v>node[x].val) erase(rs , v);
else {
node[x].cnt--;
if(node[x].cnt<=){
if(ls==&&rs==) x = ;
else if(ls == ) x = rs;
else if(rs == ) x = ls;
else{
if(node[ls].pri <node[rs].pri) rotL(x),erase(ls,v);
else rotR(x) , erase(rs , v);
}
}
}
push_up(x);
}
int getCnt(int x , int v){//从x号节点出发找到对应的子树下小于等于v的值的个数
if(x == ) return ;
int ans = ;
if(node[x].val>v) ans = getCnt(ls , v);
else if(node[x].val<v) ans = node[x].cnt+node[ls].sz+getCnt(rs , v);
else ans = node[x].cnt+node[ls].sz;
return ans;
}
}
int n , m , h[N] , a[N] , tot;
//树状数组部分
#define lowbit(x) x&(-x)
void Add(int id , int v)
{
for(int x=id ; x<=n ; x+=lowbit(x)){
Treap::insert(Treap::A[x] , v);
}
}
void Erase(int id , int v)
{
for(int x=id ; x<=n ; x+=lowbit(x)){
Treap::erase(Treap::A[x] , v);
}
}
int getSum(int p , int v)//cal 1~p区间内小于等于v的值的个数
{
int sum = ;
for(int x=p ; x> ; x-=lowbit(x)){
sum+=Treap::getCnt(Treap::A[x] , v);
}
return sum;
}
int getSumMin(int p , int v)//cal 1~p区间内小于v的值的个数
{
v--;//important保证等于的情况被排除
return getSum(p , v);
} int main()
{
// freopen("a.in" , "r" , stdin);
scanf("%d" , &n);
for(int i= ; i<=n ; i++){
scanf("%d" , &h[i]);
a[i] = h[i];
}
sort(a+ , a+n+);
tot = unique(a+ , a+n+)-(a+);
Treap::init();
int sum = ;
for(int i= ; i<=n ; i++){
h[i] = lower_bound(a+ , a+tot+ , h[i])-a;
Add(i , h[i]);
sum+=i--getSum(i- , h[i]);
}
printf("%d\n" , sum); scanf("%d" , &m);
while(m--){
// for(int i=1 ; i<=n ; i++)
// cout<<h[i]<<" ";
// cout<<endl;
int ai , bi;
scanf("%d%d" , &ai , &bi);
if(ai>bi) swap(ai , bi);
if(h[ai]<h[bi]) sum++;
else if(h[ai]>h[bi]) sum--;
else{
printf("%d\n" , sum);
continue;
}
int add = ;
if(bi-ai>){
add += getSumMin(bi- , h[bi])-getSumMin(ai , h[bi]);
add -= (bi-ai-)-(getSum(bi- , h[bi])-getSum(ai , h[bi]));
add += (bi-ai-)-(getSum(bi- , h[ai])-getSum(ai , h[ai]));
add -= getSumMin(bi- , h[ai])-getSumMin(ai , h[ai]);
} sum += add; Erase(ai , h[ai]);
Erase(bi , h[bi]);
Add(ai , h[bi]);
Add(bi , h[ai]);
swap(h[ai] , h[bi]);
printf("%d\n" , sum);
}
return ;
}

bzoj2141 树状数组套Treap树的更多相关文章

  1. BZOJ - 3295 动态逆序对 (树状数组套treap)

    题目链接 思路和bzoj2141差不多,不过这道题的数据更强一些,线段树套treapT了,树状数组套treap卡过~~ #include<bits/stdc++.h> using name ...

  2. [bzoj3196][Tyvj1730]二逼平衡树_树套树_位置线段树套非旋转Treap/树状数组套主席树/权值线段树套位置线段树

    二逼平衡树 bzoj-3196 Tyvj-1730 题目大意:请写出一个维护序列的数据结构支持:查询给定权值排名:查询区间k小值:单点修改:查询区间内定值前驱:查询区间内定值后继. 注释:$1\le ...

  3. BZOJ 3196 Tyvj 1730 二逼平衡树 ——树状数组套主席树

    [题目分析] 听说是树套树.(雾) 怒写树状数组套主席树,然后就Rank1了.23333 单点修改,区间查询+k大数查询=树状数组套主席树. [代码] #include <cstdio> ...

  4. BZOJ 1901 Zju2112 Dynamic Rankings ——树状数组套主席树

    [题目分析] BZOJ这个题目抄的挺霸气. 主席树是第一时间想到的,但是修改又很麻烦. 看了别人的题解,原来还是可以用均摊的思想,用树状数组套主席树. 学到了新的姿势,2333o(* ̄▽ ̄*)ブ [代 ...

  5. BZOJ1901 - Dynamic Rankings(树状数组套主席树)

    题目大意 给定一个有N个数字的序列,然后又m个指令,指令种类只有两种,形式如下: Q l r k 要求你查询区间[l,r]第k小的数是哪个 C i t  要求你把第i个数修改为t 题解 动态的区间第k ...

  6. bzoj 3110: [Zjoi2013]K大数查询 树状数组套线段树

    3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1384  Solved: 629[Submit][Stat ...

  7. [BZOJ 3196] 213平衡树 【线段树套set + 树状数组套线段树】

    题目链接:BZOJ - 3196 题目分析 区间Kth和区间Rank用树状数组套线段树实现,区间前驱后继用线段树套set实现. 为了节省空间,需要离线,先离散化,这样需要的数组大小可以小一些,可以卡过 ...

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

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

  9. BZOJ_3196_Tyvj 1730 二逼平衡树_树状数组套主席树

    BZOJ_3196_Tyvj 1730 二逼平衡树_树状数组套主席树 Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排 ...

随机推荐

  1. JS事件模型小结

    三种事件模型:原始事件模型(DOM0),DOM2事件模型,IE事件模型: 不同点: 事件程序的注册(给HTML元素所对应的JS对象绑定事件) 事件传播的过程 事件模型的注册: 一.原始事件模型(没有兼 ...

  2. React 高级指南小记

    接上篇,还是笔记,还是干货. 深入 JSX 如果使用 JSX 表达式 <Foo />,Foo 必须在范围内,因为这些标签被编译为对指定变量的直接引用. 由于 JSX 编译为对 React. ...

  3. Java一个汉字占几个字节(详解与原理)

    1.先说重点: 不同的编码格式占字节数是不同的,UTF-8编码下一个中文所占字节也是不确定的,可能是2个.3个.4个字节: 2.以下是源码: @Test public void test1() thr ...

  4. Rails中的缓存

    最近学习Rails. 看到如下代码: <% if notice %> <p id="notice"><%= notice %></p> ...

  5. 第三方的图片加载( Android-Universal-Image-Loader)

    Android-Universal-Image-Loader是一个开源的UI组件程序,该项目的目的是提供一个可重复使用的仪器为异步图像加载,缓存和显示. (1).使用多线程加载图片(2).灵活配置Im ...

  6. gulp入门演练

    一直想学习下gulp看了蛮多资料,然后总是感觉是是而非,突然开窍了,把自己学会的过程给大家分享下,入门超级简单的 gulp安装 安装gulp 如果参数-g 表示全局安装 $ npm install g ...

  7. Datatable+Springmvc+mybatis(分页+排序+搜索)_Jquery

    一.简介 通过Jqury的Datatable插件,构造数据列表,并且增加或者隐藏相应的列,已达到数据显示要求.同时, jQuery Datatable 强大的功能支持:排序,分页,搜索等. 二.前台分 ...

  8. hdu 5676 ztr loves lucky numbers

    题目链接:hdu 5676 一开始看题还以为和数位dp相关的,后来才发现是搜索题,我手算了下,所有的super lucky number(也就是只含数字4, 7且4, 7的数量相等的数)加起来也不过几 ...

  9. zabbix3.0.4 部署之七 (zabbix3.0.4 邮件报警) & 微信报警

    1 [root@sv-zabbix ~]# cat /usr/local/zabbix/share/zabbix/alertscripts/sendEmail.sh #!/bin/bash#SMTP_ ...

  10. [求助] win7 x64 封装 出现 Administrator.xxxxx 的问题

    [求助] win7 x64 封装 出现 Administrator.xxxxx 的问题 jacky_qu 发表于 2014-9-3 23:34:37 https://www.itsk.com/thre ...