【题目链接】 UVA11990

【题目大意】

  给出一个数列,每次删去一个数,求一个数删去之前整个数列的逆序对数。

【题解】

  一开始可以用树状数组统计出现的逆序对数量
  对于每个删去的数,我们可以用线段树求出它在原序列中的逆序对贡献
  在线段树的每个区间有序化数据,就可以二分查找出这个数在每个区间的位置,
  这样就处理出了划分出的区间的贡献,先用答案减去这一部分
  接下来考虑已经删去部分的容斥,我们发现只要对删去部分再做一次类似的操作,
  将这一部分跟当前删去数求一次贡献就是刚才多减去的部分,将这部分的答案再加回去。
  这个可以在线段树上查找的同时用树状数组维护。
  这样子就能处理每一次的删数操作了。

【代码】

#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int N=200010;
int n,m,c[30][N],a[30][N],arr[N],id[N];
long long ans;
void add(int c[],int x,int v,int n){while(x<=n)c[x]+=v,x+=x&-x;}
int sum(int c[],int x,int n=0){int s=0;while(x>n)s+=c[x],x-=x&-x;return s;}
void build(int x,int l,int r,int d){
int mid=(l+r)>>1;
for(int i=l;i<=r;i++)a[d][i]=a[d-1][i],c[d][i]=0;
if(l==r)return;
build(x<<1,l,mid,d+1);
build(x<<1|1,mid+1,r,d+1);
sort(a[d]+l,a[d]+r+1);
}
int find(int L,int R,int d,int v){
int l=L,r=R;
while(l<r){
int mid=(l+r)>>1;
if(a[d][mid]>=v)r=mid;
else l=mid+1;
}if(a[d][l]>v)l--;
return l;
}
void query(int x,int l,int r,int L,int R,int v,int d,int f){
int mid=(l+r)>>1;
if(L<=l&&r<=R){
int k=find(l,r,d,v),t=sum(c[d],k,l-1);
if(!f){k=r-k;t=sum(c[d],r,l-1)-t;}
else k-=l-1;
ans-=k-t; return;
}if(l>=r)return;
if(L<=mid)query(x<<1,l,mid,L,R,v,d+1,f);
if(R>mid)query(x<<1|1,mid+1,r,L,R,v,d+1,f);
}
void update(int x,int l,int r,int s,int v,int d){
int mid=(l+r)>>1;
if(l==r){add(c[d],l,1,r);return;}
if(l>=r)return;
if(s<=mid)update(x<<1,l,mid,s,v,d+1);
else update(x<<1|1,mid+1,r,s,v,d+1);
int k=find(l,r,d,v);
add(c[d],k,1,r);
}
int main(){
while(~scanf("%d%d",&n,&m)){
ans=0; memset(arr,0,sizeof(arr));
for(int i=1;i<=n;i++){
scanf("%d",&a[0][i]); id[a[0][i]]=i;
ans+=i-1-sum(arr,a[0][i]);
add(arr,a[0][i],1,n);
}build(1,1,n,1);
while(m--){
int k;
scanf("%d",&k);
printf("%lld\n",ans);
if(ans){
query(1,1,n,1,id[k]-1,k,1,0);
query(1,1,n,id[k]+1,n,k,1,1);
update(1,1,n,id[k],k,1);
}
}
}return 0;
}

UVA 11990 ”Dynamic“ Inversion(线段树+树状数组)的更多相关文章

  1. UVA 11990 `Dynamic'' Inversion CDQ分治, 归并排序, 树状数组, 尺取法, 三偏序统计 难度: 2

    题目 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&a ...

  2. UVA 11990 ``Dynamic'' Inversion 动态逆序对

    ``Dynamic'' Inversion Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 https://uva.onlinejudge.org/index ...

  3. UVA 11990 ``Dynamic'' Inversion (序列分治)

    26天以前做过的一道题,之前的做法是分治预处理,树套树在线修改,复杂度为O(nlogn+m*logn*logn),代码量较大. 本来想学习一下cdq分治的,看到论文上的凸包.斜率就暂时放一边了,只知道 ...

  4. UVA 11990 ``Dynamic'' Inversion (线段树套BIT,分治)

    题目要求可转化为查询一个区间内有多少数比val大(或者小). 区间用线段树分解(logN),每个区间维护一rank树. rank可用BIT查询,往BIT里面插值,为了保证不同区间的BIT互不影响要先离 ...

  5. CodeForces -163E :e-Government (AC自动机+DFS序+树状数组)

    The best programmers of Embezzland compete to develop a part of the project called "e-Governmen ...

  6. [bzoj1901][zoj2112][Dynamic Rankings] (整体二分+树状数组 or 动态开点线段树 or 主席树)

    Dynamic Rankings Time Limit: 10 Seconds      Memory Limit: 32768 KB The Company Dynamic Rankings has ...

  7. HDU 1394 Minimum Inversion Number(最小逆序数/暴力 线段树 树状数组 归并排序)

    题目链接: 传送门 Minimum Inversion Number Time Limit: 1000MS     Memory Limit: 32768 K Description The inve ...

  8. HDU 1394 Minimum Inversion Number(线段树/树状数组求逆序数)

    Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java ...

  9. bzoj 1901 Dynamic Rankings (树状数组套线段树)

    1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec  Memory Limit: 128 MB Description 给定一个含有n个数的序列a[1] ...

随机推荐

  1. httpclient传参类型与响应参数接收

    https://blog.csdn.net/qq_26562641/article/details/72817457 https://blog.csdn.net/chenjf0221/article/ ...

  2. ssh.sh_for_ubuntu1404

    #!/bin/bash sed -i 's/PermitRootLogin without-password/PermitRootLogin yes/g' /etc/ssh/sshd_config s ...

  3. hnust 档案管理

    问题 E: 档案管理 时间限制: 1 Sec  内存限制: 128 MB提交: 274  解决: 105[提交][状态][讨论版] 题目描述 X老师管理着学校的档案室,经常会有其他的老师来档案室存文件 ...

  4. JavaSE复习(一)继承多态与常用API

    继承与多态 在父子类的继承关系当中,如果成员变量重名,则创建子类对象时,访问有两种方式: 直接通过子类对象访问成员变量:等号左边是谁,就优先用谁,没有则向上找 间接通过成员方法访问成员变量:该方法属于 ...

  5. 微信小程序--背景图片手机无法预览

    目前小程序好像没有支持手机预览背景本地图片,所以将本地图片改为网络图片链接就可以了 background: url("https://..../img/no.png") no-re ...

  6. hdu1877进制转换

    #include <stdio.h> int m; void Ck(int n) { if(n>=m) Ck(n/m); printf("%d",n%m); } ...

  7. InfluxDB数据备份和恢复方法,支持本地和远程备份

    本文属于<InfluxDB系列教程>文章系列,该系列共包括以下 17 部分: InfluxDB学习之InfluxDB的基本概念 InfluxDB学习之InfluxDB的基本操作 Influ ...

  8. 【bzoj2238】Mst 最小生成树+树链剖分+线段树

    题目描述 给出一个N个点M条边的无向带权图,以及Q个询问,每次询问在图中删掉一条边后图的最小生成树.(各询问间独立,每次询问不对之后的询问产生影响,即被删掉的边在下一条询问中依然存在) 输入 第一行两 ...

  9. GIS专业分析方法(待更新)

    遗传算法 核密度估计 http://blog.163.com/zhuandi_h/blog/static/1802702882012111092743556/ http://blog.csdn.net ...

  10. 如何进入百度、阿里,一个6年Android老司机的面经

    花絮 也许会有人感叹某些人的运气比较好,但是他们不曾知道对方吃过多少苦,受过多少委屈.某些时候就是需要我们用心去发现突破点,然后顺势而上,抓住机遇,那么你将会走向另外一条大道,成就另外一个全新的自我. ...