UVA 11990 ``Dynamic'' Inversion (线段树套BIT,分治)
题目要求可转化为查询一个区间内有多少数比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,分治)的更多相关文章
- UVA 11990 ”Dynamic“ Inversion(线段树+树状数组)
[题目链接] UVA11990 [题目大意] 给出一个数列,每次删去一个数,求一个数删去之前整个数列的逆序对数. [题解] 一开始可以用树状数组统计出现的逆序对数量 对于每个删去的数,我们可以用线段树 ...
- UVA 11990 ``Dynamic'' Inversion 动态逆序对
``Dynamic'' Inversion Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 https://uva.onlinejudge.org/index ...
- uva 12003 Array Transformer (线段树套平衡树)
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&p ...
- BZOJ.1901.Dynamic Rankings(线段树套平衡树 Splay)
题目链接or Here 题意:n个数,有两个操作:1.修改某个数为v:2.询问一段区间第k小的数 如果没有修改,则可以用线段树,每个节点P[a,b]存储大小为b-a+1的数组,代表其中的数 同时,这个 ...
- UVA 11990 ``Dynamic'' Inversion (序列分治)
26天以前做过的一道题,之前的做法是分治预处理,树套树在线修改,复杂度为O(nlogn+m*logn*logn),代码量较大. 本来想学习一下cdq分治的,看到论文上的凸包.斜率就暂时放一边了,只知道 ...
- UVA 11990 `Dynamic'' Inversion CDQ分治, 归并排序, 树状数组, 尺取法, 三偏序统计 难度: 2
题目 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&a ...
- [BZOJ 1901] Dynamic Rankings 【树状数组套线段树 || 线段树套线段树】
题目链接:BZOJ - 1901 题目分析 树状数组套线段树或线段树套线段树都可以解决这道题. 第一层是区间,第二层是权值. 空间复杂度和时间复杂度均为 O(n log^2 n). 线段树比树状数组麻 ...
- BZOJ 1901: Zju2112 Dynamic Rankings 区间k大 带修改 在线 线段树套平衡树
之前写线段树套splay数组版..写了6.2k..然后弃疗了.现在发现还是很水的..嘎嘎.. zju过不了,超时. upd:才发现zju是多组数据..TLE一版才发现.然后改了,MLE...手写内存池 ...
- 树套树Day1线段树套平衡树bzoj3196
您需要写一种数据结构,来维护一个有序数列,其中需要提供以下操作:1.查询k在区间内的排名2.查询区间内排名为k的值3.修改某一位值上的数值4.查询k在区间内的前驱(前驱定义为小于x,且最大的数)5.查 ...
随机推荐
- Linux中网卡相关命令以及SSH连接远程主机
ifconfig 命令 查看与配置网络状态命令 关闭与启动网卡 ifdown 网卡设备名 禁用该网卡设备 ifup 网卡设备名 启用该网卡设备 查询网络状态 netstat 选项 -t 列出TCP协议 ...
- c++第六次实验
part 1 验证性实验 合并两个文件.虽说验证,但后两个实验均受该代码指导启发. part 2 文末添加数据 1.代码 #include<fstream> #include<io ...
- java解析xml文件练习——通过应用包名获取应用图标即其他信息(基于魅族应用商店)
1.解析包名数据文件(txt文件),并生成包名数组: package jsouphtml; import java.io.BufferedReader; import java.io.File; im ...
- hdu6070(分数规划/二分+线段树区间更新,区间最值)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=6070 题意: 给出一个题目提交序列, 从中选出一个正确率最小的子串. 选中的子串中每个题目当且仅当最 ...
- 51nod1118(递推)
题目链接: https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1118 题意: 中文题诶~ 思路: 因为机器人只能往下或者右 ...
- bzoj1934: [Shoi2007]Vote 善意的投票(最小割)
传送门 考虑源点为同意,汇点为反对,那么只要源点向同意的连边,不同意的向汇点连边,求个最小割就是答案 然后考虑朋友之间怎么办,我们令朋友之间连双向边.这样不管怎么割都能对应一种选择情况.那么还是求一个 ...
- Ryzen 移动平台上安装 Gentoo Linux
Linux 内核对于跟进支持 Ryzen 移动低压 CPU 的热情似乎和市面上寥寥无几的 Ryzen 笔记本热度十分吻合.虽然从 Linux 4.11 起就对 Ryzen 桌面 CPU 有较好的支持, ...
- CentOS编译安装GCC 4.9.2成功
在Linux上编译安装gcc是个寻烦恼的活,对于像我这样习惯于在Windows上面使用二进制安装包的人来说,自已编译安装gcc是个相当大的挑战,今天直接挑战最新版的gcc,是4.9.2版本的,做之前查 ...
- [题解](排列组合)luogu_P3223排队
把老师和女生插到男生中间,先对男生排列:A(n,n),然后把老师插到n+1个空里:A(n+1,2),然后放入女生:A(n+3,m) 但是少考虑了老师之间由1个女生分开的情况,所以把三个人看作一个整体, ...
- python3 下载 以及 练习1 以及 pycharm 专业版 安装
下载python: https://www.python.org/downloads/release/python-365/ ########sample 1 下载pycharm 社区版本,但是web ...