用树套树来解决这个问题,存储每个节点的数值是多少,然后交换

对于答案的变更可以讨论下,假设交换的是x,y位置的数x<=y

如果x=y || high[x]=high[y]则对答案没有影响

如果high[x]<high[y],那么首先交换x,y会对这两个点的逆序对数增加1,否则减小1

那么这是对于这两个数中间的数的逆序对的影响就是:

x的移动会令在这个区间里比x权值小的数与x不在为逆序对,所以答案减少个数

同时令比x的权值大的数多一个与x的逆序对,所以答案增加个数。

y类似,在此不再赘述

/**************************************************************
    Problem:
    User: BLADEVIL
    Language: Pascal
    Result: Accepted
    Time: ms
    Memory: kb
****************************************************************/
 
//By BLADEVIL
type
    rec                     =record
        left, right, root   :longint;
    end;
     
var
    n, m                    :longint;
    high                    :array[..] of longint;
    t                       :array[..] of rec;
    b_left, b_right, b_key  :array[..] of longint;
    b_size                  :array[..] of longint;
    tot                     :longint;
    ans                     :longint;
     
procedure swap(var a,b:longint);
var
    c                       :longint;
begin
    c:=a; a:=b; b:=c;
end;
     
procedure left_rotate(var t:longint);
var
    k                       :longint;
begin
    k:=b_right[t];
    b_right[t]:=b_left[k];
    b_left[k]:=t;
    b_size[k]:=b_size[t];
    b_size[t]:=b_size[b_left[t]]+b_size[b_right[t]]+;
    t:=k;
end;   
 
procedure right_rotate(var t:longint);
var
    k                       :longint;
begin
    k:=b_left[t];
    b_left[t]:=b_right[k];
    b_right[k]:=t;
    b_size[k]:=b_size[t];
    b_size[t]:=b_size[b_left[t]]+b_size[b_right[t]]+;
    t:=k;
end;
     
procedure maintain(var t:longint;flag:boolean);
begin
    if not flag then
    begin
        if b_size[b_left[b_left[t]]]>b_size[b_right[t]] then
            right_rotate(t) else
        if b_size[b_right[b_left[t]]]>b_size[b_right[t]] then
        begin
            left_rotate(b_left[t]);
            right_rotate(t);
        end else exit; 
    end else
    begin
        if b_size[b_right[b_right[t]]]>b_size[b_left[t]] then
            left_rotate(t) else
        if b_size[b_left[b_right[t]]]>b_size[b_left[t]] then
        begin
            right_rotate(b_right[t]);
            left_rotate(t);
        end else exit;
    end;
    maintain(b_left[t],false);
    maintain(b_right[t],true);
    maintain(t,true);
    maintain(t,false);
end;
     
procedure insert(var t:longint;v:longint);
begin
    if t= then
    begin
        inc(tot);
        t:=tot;
        b_size[t]:=;
        b_left[t]:=;
        b_right[t]:=;
        b_key[t]:=v;
    end else
    begin
        inc(b_size[t]);
        if v<b_key[t] then insert(b_left[t],v) else insert(b_right[t],v);
        maintain(t,v>=b_key[t]);
    end;
end;
 
function b_delete(var t:longint;v:longint):longint;
begin
    dec(b_size[t]);
    if (b_key[t]=v) or (v>b_key[t]) and (b_right[t]=) or (v<b_key[t]) and (b_left[t]=) then
    begin
        b_delete:=b_key[t];
        if (b_left[t]=) or (b_right[t]=) then t:=b_left[t]+b_right[t] else
            b_key[t]:=b_delete(b_left[t],v+);
    end else
        if v>=b_key[t] then exit(b_delete(b_right[t],v)) else exit(b_delete(b_left[t],v));
end;
     
procedure build(x,l,r:longint);
var
    mid                     :longint;
    i                       :longint;
begin
    t[x].left:=l; t[x].right:=r; t[x].root:=;
    for i:=l to r do insert(t[x].root,high[i]);
    if l=r then exit;
    with t[x] do mid:=(left+right) div ;
    build(*x,l,mid);
    build(*x+,mid+,r);
end;
 
function b_less(var t:longint;v:longint):longint;
begin
    if t= then exit();
    if b_key[t]>=v then exit(b_less(b_left[t],v)) else
        exit(b_size[b_left[t]]++b_less(b_right[t],v));
end;
 
function less(x,l,r,v:longint):longint;
var
    mid                     :longint;
begin
    if (t[x].left=l) and (t[x].right=r) then
        exit(b_less(t[x].root,v));
    with t[x] do mid:=(left+right) div ;
    if mid<l then exit(less(*x+,l,r,v)) else
    if mid>=r then exit(less(*x,l,r,v)) else
        exit(less(*x,l,mid,v)+less(*x+,mid+,r,v));
end;
 
function b_greater(var t:longint; v:longint):longint;
begin
    if t= then exit();
    if b_key[t]<=v then exit(b_greater(b_right[t],v)) else
        exit(b_size[b_right[t]]++b_greater(b_left[t],v));
end;
 
function greater(x,l,r,v:longint):longint;
var
    mid                     :longint;
begin
    if (t[x].left=l) and (t[x].right=r) then
        exit(b_greater(t[x].root,v));
    with t[x] do mid:=(left+right) div ;
    if mid<l then exit(greater(*x+,l,r,v)) else
    if mid>=r then exit(greater(*x,l,r,v)) else
        exit(greater(*x,l,mid,v)+greater(*x+,mid+,r,v));
end;
 
procedure change(x,y,v:longint);
var
    mid                     :longint;
begin
    insert(t[x].root,v);
    if (t[x].left=t[x].right) then exit;
    with t[x] do mid:=(left+right) div ;
    if mid<y then change(*x+,y,v) else change(*x,y,v);
end;
 
procedure delete(x,y,v:longint);
var
    mid                     :longint;
begin
    b_delete(t[x].root,v);
    if (t[x].left=t[x].right) then exit;
    with t[x] do mid:=(left+right) div ;
    if mid<y then delete(*x+,y,v) else delete(*x,y,v);
end;
 
procedure init;
var
    i                       :longint;
begin
    read(n);
    for i:= to n do read(high[i]);
    build(,,n);
end;
 
procedure main;
var
    i                       :longint;
    x, y                    :longint;
     
begin  
    read(m);
    for i:= to n- do
        ans:=ans+less(,i+,n,high[i]);
    writeln(ans);
    for i:= to m do
    begin
        read(x,y);
        if (x=y) or (high[x]=high[y]) then
        begin
            writeln(ans);
            continue;
        end;
        if x>y then swap(x,y);
        if high[x]<high[y] then inc(ans) else dec(ans);
        if x+<>y then
        begin
            ans:=ans-less(,x+,y-,high[x]);
            ans:=ans+greater(,x+,y-,high[x]);
            ans:=ans+less(,x+,y-,high[y]);
            ans:=ans-greater(,x+,y-,high[y]);
        end;
        delete(,x,high[x]);
        change(,x,high[y]);
        delete(,y,high[y]);
        change(,y,high[x]);
        swap(high[x],high[y]);
        writeln(ans);
    end;
end;
 
begin
    init;
    main;
end.

bzoj 2141 线段树套平衡树的更多相关文章

  1. bzoj 2120 线段树套平衡树

    先吐下槽,改了快一个小时,最后发现是SBT的delete写错了,顿时就有想死的心..... 首先对于这道题,我们应该先做一下他的小问题,bzoj1878,虽然和这道题几乎一点关系没有, 但是能给我们一 ...

  2. bzoj 1901 线段树套平衡树+二分答案查询

    我们就建一颗线段树,线段树的每一个节点都是一颗平衡树,对于每个询问来说,我们就二分答案, 查询每个二分到的mid在这个区间里的rank,然后就行了 /************************* ...

  3. BZOJ 3196 线段树套平衡树

    (代码无比丑陋) //By SiriusRen #include <cstdio> #include <algorithm> using namespace std; int ...

  4. bzoj 3196/ Tyvj 1730 二逼平衡树 (线段树套平衡树)

    3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description ...

  5. 【BZOJ-3196】二逼平衡树 线段树 + Splay (线段树套平衡树)

    3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2271  Solved: 935[Submit][Stat ...

  6. CF 19D - Points 线段树套平衡树

    题目在这: 给出三种操作: 1.增加点(x,y) 2.删除点(x,y) 3.询问在点(x,y)右上方的点,如果有相同,输出最左边的,如果还有相同,输出最低的那个点 分析: 线段树套平衡树. 我们先离散 ...

  7. BZOJ3196二逼平衡树——线段树套平衡树(treap)

    此为平衡树系列最后一道:二逼平衡树您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名2.查询区间内排名为k的值3.修改某一位值上的数值4.查询 ...

  8. P3380 【模板】二逼平衡树(树套树)(线段树套平衡树)

    P3380 [模板]二逼平衡树(树套树) 前置芝士 P3369 [模板]普通平衡树 线段树套平衡树 这里写的是线段树+splay(不吸氧竟然卡过了) 对线段树的每个节点都维护一颗平衡树 每次把给定区间 ...

  9. [BZOJ1146][CTSC2008]网络管理Network(二分+树链剖分+线段树套平衡树)

    题意:树上单点修改,询问链上k大值. 思路: 1.DFS序+树状数组套主席树 首先按照套路,关于k大值的问题,肯定要上主席树,每个点维护一棵权值线段树记录它到根的信息. 关于询问,就是Que(u)+Q ...

随机推荐

  1. WordPress 非插件实现拦截无中文留言

    Some Chinese Please 插件可以拦截不带中文字的留言,之前本博客一直在用效果不错,不写入数据库,可有效地减少 spam 对服务器的无谓使用,其实可以将插件简化一下,直接用代码实现.将下 ...

  2. mac brew install redis

    在mac 下安装redis 执行brew install redis ==> Downloading http://download.redis.io/releases/redis-2.8.19 ...

  3. Thinkphp 下面执行crond

    thinkphp开启cli支持  1.tp正好支持cli命令模式,手册的路径为13.7.4 如果是用的其他框架不支持cli,那么只能直接写程序了,其实就是写面向过程的最基础的php代码. 2.在入口文 ...

  4. mysql 根据生日计算年龄,并查询在18-25之间的语句

    select id, DATE_FORMAT(birthday,"%Y-%m-%d") birthday, CURDATE() , (year(now())-year(birthd ...

  5. 基于Memcached的Session共享问题

    把Memcached的key(Guid)写入浏览器的cookie(类比SessionId) 存值: string sessionId = Guid.NewGuid().ToString(); Comm ...

  6. 4.css度量单位

    在 CSS 长度设置中,我们经常需要使用到度量单位,即以什么样的单位设计我们的字 体或边框长度.而在 CSS 中长度单位又分为绝对长度和相对长度. 绝对长度指的是现实世界的度量单位,CSS 支持五种绝 ...

  7. Python超简单的HTTP服务器

    Python超简单的HTTP服务器 安装了python就可以 python -m SimpleHTTPServer 执行这一个命令即可实现一个HTTP服务器,将当前目录设为HTTP服务目录,可以通过h ...

  8. eval和new Function的区别

    eval和new Function都可以动态解析和执行字符串.但是它们对解析内容的运行环境判定不同. var a = 'global scope' function b(){ var a = 'loc ...

  9. C 基于UDP实现一个简易的聊天室

    引言 本文是围绕Linux udp api 构建一个简易的多人聊天室.重点看思路,帮助我们加深 对udp开发中一些api了解.相对而言udp socket开发相比tcp socket开发注意的细节要少 ...

  10. hdu1007

    Have you ever played quoit in a playground? Quoit is a game in which flat rings are pitched at some ...