BZOJ 2141 排队(树状数组套treap)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2141
题意:给出一个数列A,每次交换两个数的位置。输出交换后逆序对的个数。
思路:首先,对于交换位置x和y,对于区间[x+1,y-1]的数字,小于A[x]的要减去,大于A[x]的要加上,大于A[y]的要减去,小于A[y] 的要加上。然后A[x]<A[y]则答案加1,A[x]<A[y]答案要减去1。查找修改用树状数组套一个treap即可。
struct node
{
int val,size,pri,L,R,cnt;
};
node a[N*300];
int e;
int newNode(int val)
{
int x=++e;;
a[x].val=val;
a[x].size=1;
a[x].cnt=1;
a[x].L=a[x].R=0;
a[x].pri=rand();
return x;
}
void pushUp(int x)
{
if(x==0) return;
a[x].size=a[x].cnt+a[a[x].L].size+a[a[x].R].size;
}
void rotL(int &x)
{
int y=a[x].R;
a[x].R=a[y].L;
a[y].L=x;
pushUp(x);
pushUp(y);
x=y;
}
void rotR(int &x)
{
int y=a[x].L;
a[x].L=a[y].R;
a[y].R=x;
pushUp(x);
pushUp(y);
x=y;
}
void insert(int &k,int val)
{
if(k==0) k=newNode(val);
else if(val<a[k].val)
{
insert(a[k].L,val);
if(a[a[k].L].pri>a[k].pri) rotR(k);
}
else if(val>a[k].val)
{
insert(a[k].R,val);
if(a[a[k].R].pri>a[k].pri) rotL(k);
}
else a[k].cnt++;
pushUp(k);
}
void del(int val,int &k)
{
if(k==0) return;
else if(val<a[k].val) del(val,a[k].L);
else if(val>a[k].val) del(val,a[k].R);
else
{
a[k].cnt--;
if(a[k].cnt<=0)
{
if(a[k].L==0&&a[k].R==0) k=0;
else if(a[k].L==0) k=a[k].R;
else if(a[k].R==0) k=a[k].L;
else
{
if(a[a[k].L].pri<a[a[k].R].pri) rotL(k),del(val,a[k].L);
else rotR(k),del(val,a[k].R);
}
}
}
pushUp(k);
}
int d[N];
int getCnt(int t,int x)
{
if(t==0) return 0;
if(a[t].val==x)
{
return a[a[t].L].size+a[t].cnt;
}
if(a[t].val>x) return getCnt(a[t].L,x);
return a[t].cnt+a[a[t].L].size+getCnt(a[t].R,x);
}
int n,m;
int A[N];
void Set(int x,int k)
{
while(x<=n)
{
insert(A[x],k);
x+=x&-x;
}
}
void erase(int x,int k)
{
while(x<=n)
{
del(k,A[x]);
x+=x&-x;
}
}
int get(int x,int k)
{
int ans=0;
while(x)
{
ans+=getCnt(A[x],k);
x-=x&-x;
}
return ans;
}
pair<int,int> cal(int L,int R,int x)
{
i64 a=get(R,x)-get(L-1,x);
i64 b=get(R,x-1)-get(L-1,x-1);
return MP(a-b,b);
}
int p[N];
int find(int low,int high,int x)
{
int M;
while(low<=high)
{
M=(low+high)>>1;
if(p[M]==x) return M;
if(p[M]>x) high=M-1;
else low=M+1;
}
}
void getInt(int &x)
{
char c=getchar();
while(!isdigit(c)) c=getchar();
x=0;
while(isdigit(c)) x=x*10+c-'0',c=getchar();
}
int main()
{
getInt(n);
int i;
FOR1(i,n) getInt(d[i]),p[i]=d[i];
sort(p+1,p+n+1);
int M=unique(p+1,p+n+1)-(p+1);
FOR1(i,n) d[i]=find(1,M,d[i]);
i64 sum=0;
pair<int,int> temp;
FOR1(i,n)
{
Set(i,d[i]);
temp=cal(1,i-1,d[i]);
sum+=i-1-temp.first-temp.second;
}
PR(sum);
RD(m);
int x,y;
while(m--)
{
getInt(x);
getInt(y);
if(x>y) swap(x,y);
if(d[x]==d[y])
{
PR(sum);
continue;
}
if(d[x]>d[y]) sum--;
else sum++;
if(y-x>1)
{
temp=cal(x+1,y-1,d[x]);
sum-=temp.second;
sum+=y-x-1-temp.first-temp.second;
temp=cal(x+1,y-1,d[y]);
sum+=temp.second;
sum-=y-x-1-temp.first-temp.second;
}
erase(x,d[x]);
erase(y,d[y]);
swap(d[x],d[y]);
Set(x,d[x]);
Set(y,d[y]);
PR(sum);
}
}
BZOJ 2141 排队(树状数组套treap)的更多相关文章
- BZOJ 2141 排队(树状数组套主席树)
解法很多的题,可以块套树状数组,可以线段树套平衡树.我用的是树状数组套主席树. 题意:给出一段数列,m次操作,每次操作是交换两个位置的数,求每次操作后的逆序对数.(n,m<=2e4). 对于没有 ...
- BZOJ - 3295 动态逆序对 (树状数组套treap)
题目链接 思路和bzoj2141差不多,不过这道题的数据更强一些,线段树套treapT了,树状数组套treap卡过~~ #include<bits/stdc++.h> using name ...
- BZOJ2141排队——树状数组套权值线段树(带修改的主席树)
题目描述 排排坐,吃果果,生果甜嗦嗦,大家笑呵呵.你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家 乐和和.红星幼儿园的小朋友们排起了长长地队伍,准备吃果果.不过因为小朋友们的身高有所区别 ...
- bzoj2141 树状数组套Treap树
题目大意是在能够改变两个数的位置的情况下计算逆序对数 这因为是动态记录逆序对 本来单纯逆序对只要用树状数组计算即可,但这里因为更新,所以利用TReap树的删点和增加点来进行更新 大致是把每个树状数组所 ...
- HDU 5618 Jam's problem again (cdq分治+BIT 或 树状数组套Treap)
题意:给n个点,求每一个点的满足 x y z 都小于等于它的其他点的个数. 析:三维的,第一维直接排序就好按下标来,第二维按值来,第三维用数状数组维即可. 代码如下: cdq 分治: #pragma ...
- BZOJ 1901 Zju2112 Dynamic Rankings ——树状数组套主席树
[题目分析] BZOJ这个题目抄的挺霸气. 主席树是第一时间想到的,但是修改又很麻烦. 看了别人的题解,原来还是可以用均摊的思想,用树状数组套主席树. 学到了新的姿势,2333o(* ̄▽ ̄*)ブ [代 ...
- 【BZOJ】1901: Zju2112 Dynamic Rankings(区间第k小+树状数组套主席树)
http://www.lydsy.com/JudgeOnline/problem.php?id=1901 首先还是吐槽时间,我在zoj交无限tle啊!!!!!!!!我一直以为是程序错了啊啊啊啊啊啊. ...
- [BZOJ 3196] 213平衡树 【线段树套set + 树状数组套线段树】
题目链接:BZOJ - 3196 题目分析 区间Kth和区间Rank用树状数组套线段树实现,区间前驱后继用线段树套set实现. 为了节省空间,需要离线,先离散化,这样需要的数组大小可以小一些,可以卡过 ...
- [BZOJ 1901] Dynamic Rankings 【树状数组套线段树 || 线段树套线段树】
题目链接:BZOJ - 1901 题目分析 树状数组套线段树或线段树套线段树都可以解决这道题. 第一层是区间,第二层是权值. 空间复杂度和时间复杂度均为 O(n log^2 n). 线段树比树状数组麻 ...
随机推荐
- 排序的本质是什么 冒泡排序 bubble sort
import random def getRandomNums(min=4, max=20): n = random.randint(min, max) arr = [random.randint(1 ...
- Charles maplocal 时中文显示乱码问题
用Charles对request进行Map Local后,app上看返回的中文是乱码? 是Map Local的文件编码有问题?是Charles设置有问题?是电脑环境有问题?哈哈,都不是 你是Andro ...
- JS模块化编程(四)--require应用
获取&使用require.js 下载最新版的Require.JS.下载之后,把它放在项目的脚本文件夹下,比如 js 文件夹下,项目结构看上去应该是: 要充分使用Require.JS,将html ...
- python 全局变量引用与修改
一.引用 使用到的全局变量只是作为引用,不在函数中修改它的值的话,不需要加global关键字.如: #! /usr/bin/python a = 1 b = [2, 3] def func(): if ...
- Java非静态内部类为什么不能有静态成员
我们可以把InnerClass看成OuterClass的非静态成员,它的初始化必须在外部类对象创建后以后进行,要加载InnerClass必须在实例化OuterClass之后完成 ,java虚拟机要求所 ...
- WordPress 3.8 后台仪表盘将重新设计
WordPress 3.8 的后台仪表盘界面将会重新设计 概况(RightNow) -> 改为网站内容(SiteContent) 快速发布(QuickPress) -> 改为快速草稿(Qu ...
- (转)Kangle配置文件
kangle配置文件 (重定向自Kangle配置文件) 目录 [隐藏] 1配置文件介绍 2重新加载配置文件 3config 3.1request和response(配置访问控制) 3.2listen( ...
- 如何实现在H5里调起高德地图APP?
http://www.cnblogs.com/milkmap/p/5912350.html 这一篇文章,将讲述如何在H5里调起高德地图APP,并展示兴趣点.适合于展示某个餐馆,商场等,让用户自行选择前 ...
- [LeetCode] 687. Longest Univalue Path_Easy tag: DFS recursive
Given a binary tree, find the length of the longest path where each node in the path has the same va ...
- [LeetCode] 103. Binary Tree Zigzag Level Order Traversal _ Medium tag: BFS
Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to ...