bzoj 2141 线段树套平衡树
用树套树来解决这个问题,存储每个节点的数值是多少,然后交换
对于答案的变更可以讨论下,假设交换的是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 线段树套平衡树的更多相关文章
- bzoj 2120 线段树套平衡树
先吐下槽,改了快一个小时,最后发现是SBT的delete写错了,顿时就有想死的心..... 首先对于这道题,我们应该先做一下他的小问题,bzoj1878,虽然和这道题几乎一点关系没有, 但是能给我们一 ...
- bzoj 1901 线段树套平衡树+二分答案查询
我们就建一颗线段树,线段树的每一个节点都是一颗平衡树,对于每个询问来说,我们就二分答案, 查询每个二分到的mid在这个区间里的rank,然后就行了 /************************* ...
- BZOJ 3196 线段树套平衡树
(代码无比丑陋) //By SiriusRen #include <cstdio> #include <algorithm> using namespace std; int ...
- bzoj 3196/ Tyvj 1730 二逼平衡树 (线段树套平衡树)
3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec Memory Limit: 128 MB[Submit][Status][Discuss] Description ...
- 【BZOJ-3196】二逼平衡树 线段树 + Splay (线段树套平衡树)
3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2271 Solved: 935[Submit][Stat ...
- CF 19D - Points 线段树套平衡树
题目在这: 给出三种操作: 1.增加点(x,y) 2.删除点(x,y) 3.询问在点(x,y)右上方的点,如果有相同,输出最左边的,如果还有相同,输出最低的那个点 分析: 线段树套平衡树. 我们先离散 ...
- BZOJ3196二逼平衡树——线段树套平衡树(treap)
此为平衡树系列最后一道:二逼平衡树您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名2.查询区间内排名为k的值3.修改某一位值上的数值4.查询 ...
- P3380 【模板】二逼平衡树(树套树)(线段树套平衡树)
P3380 [模板]二逼平衡树(树套树) 前置芝士 P3369 [模板]普通平衡树 线段树套平衡树 这里写的是线段树+splay(不吸氧竟然卡过了) 对线段树的每个节点都维护一颗平衡树 每次把给定区间 ...
- [BZOJ1146][CTSC2008]网络管理Network(二分+树链剖分+线段树套平衡树)
题意:树上单点修改,询问链上k大值. 思路: 1.DFS序+树状数组套主席树 首先按照套路,关于k大值的问题,肯定要上主席树,每个点维护一棵权值线段树记录它到根的信息. 关于询问,就是Que(u)+Q ...
随机推荐
- [leetcode]_Add Two Numbers
题目:两个链表存储数字,然后求和,和值存储在一个链表中. 代码: public ListNode addTwoNumbers(ListNode l1, ListNode l2) { ListNode ...
- Silverlight Color的颜色值
1.MainPage.xaml <UserControl xmlns:SysManage="clr-namespace:Application" x:Class=" ...
- PHP判断用户所在国家并跳转对应的目录
<?php // 淘宝API查询国家代码 $url = "http://ip.taobao.com/service/getIpInfo.php?ip=".get_client ...
- 重回程序员之路。重写博客。我的ecshop小京东二开问题汇总与解决方案。
问题1:混合支付(余额支付+在线支付)不跟更新订单状态问题. 解决方案:http://bbs.ecshop.com/viewthread.php?tid=156761&highlight= i ...
- MSSQL 所有表中模糊查询
--搜索指定数据在那个对象中存在.txt(所有表中模糊查询) CREATE PROC sp_ValueSearch @value sql_variant, --要搜索的数据 @precision bi ...
- Android去除CPU占用过高时屏幕四周闪红框
话说有些时间没有更新博客了,今天正好解决这个问题,顺便把它记录下来.. 今天遇到的情况是这样的,当CPU占用过高时,屏幕四周会出现一个红框. 闪一次两次算了,但是挺萌的(TMD)不停的闪,我的钛合金狗 ...
- i++与++i的误解
javap -c xx.class {i=0i=i++}0: bipush 02: istore_1 stack ->var13: iload_1 var1->stack4: iinc 1 ...
- 【javascript】随手记代码
//js实现的当前界面的刷新.前进.后退 <input type="button" value="刷新" onclick="window.loc ...
- WPF自定义控件(一)——Button
接触WPF也有两个多月了,有了一定的理论基础和项目经验,现在打算写一个系列,做出来一个WPF的控件库.一方面可以加强自己的水平,另一方面可以给正在学习WPF的同行一个参考.本人水平有限,难免有一些错误 ...
- StyleCop学习笔记——默认的规则
在StyleCop中有一些官方自己写好的检测规则下面就是英文的解释 文档规则 1.SA1600:ElementsMustBeDocumented元素必须添加注释 2.SA1601: PartialEl ...