``Dynamic'' Inversion

Time Limit: 20 Sec

Memory Limit: 256 MB

题目连接

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3141

Description

You are given a permutation f1,2,3,. . . ,ng. Remove m of them one by one, and output the number of
inversion pairs before each removal. The number of inversion pairs of an array A is the number of
ordered pairs (i; j) such that i < j and A[i] > A[j].

Input

The input contains several test cases. The rst line of each case contains two integers n and m
(1 n 200;000, 1 m 100;000). After that, n lines follow, representing the initial permutation.
Then m lines follow, representing the removed integers, in the order of the removals. No integer will
be removed twice. The input is terminated by end-of-le (EOF).

Output

For each removal, output the number of inversion pairs before it.
Explanation: (1,5,3,4,2)->(1,3,4,2)->(3,4,2)->(3,2)->(3)

Sample Input

5 4
1
5
3
4
2
5
1
4
2

Sample Output

5
2
2
1

HINT

题意

给你n个数,然后有m次操作,每次操作可以删除一个数

然后问你每次删除之前,还有多少个逆序对

题解:

对于每个数关于逆序对的贡献,就是

这个数前面有多少个数比他大,后面有多少个数比他小

这就是贡献~

然后我们就树状数组套treap来维护这些信息就好了

线段树会TLE。。。

代码:

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<cstring>
#include<ctime>
using namespace std;
inline long long read()
{long long x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;
}
#define maxn 12200005
long long tmp = 0;
int a[maxn];
int pos[maxn];
int n,m;
////treap
struct Treap
{int root[maxn],sz,s[maxn],ls[maxn],rs[maxn],v[maxn],w[maxn],rnd[maxn];void init(){memset(root,0,sizeof(root));sz=0;}void Updata(int k){s[k]=s[ls[k]]+s[rs[k]]+w[k];}void Rturn(int &k){int t;t=ls[k],ls[k]=rs[t],rs[t]=k,s[t]=s[k];Updata(k);k=t;}void Lturn(int &k){int t;t=rs[k],rs[k]=ls[t],ls[t]=k,s[t]=s[k];Updata(k);k=t;}void Insert(int &k,int num){if(!k){k=++sz;s[k]=w[k]=1;ls[k]=rs[k]=0;rnd[k]=rand();v[k]=num;return;}s[k]++;if(v[k]==num)w[k]++;else if(num<v[k]){Insert(ls[k],num);if(rnd[ls[k]]<rnd[k])Rturn(k);}else{Insert(rs[k],num);if(rnd[rs[k]]<rnd[k])Lturn(k);}}void Del(int &k,int num){if(v[k]==num){if(w[k]>1){w[k]--;s[k]--;return;}if(ls[k]*rs[k]==0)k=ls[k]+rs[k];else if(rnd[ls[k]]<rnd[rs[k]])Rturn(k),Del(k,num);elseLturn(k),Del(k,num);}else if(num<v[k]){Del(ls[k],num);s[k]--;}else{Del(rs[k],num);s[k]--;}}void Find(int k,int num){if(!k)return;if(v[k]<=num){tmp+=s[ls[k]]+w[k];Find(rs[k],num);}else Find(ls[k],num);}
}Tr;//线段树
int lowbit(int x)
{return x&(-x);
}
void Bit_updata(int x,int v)
{for(;x<=n+10;x+=lowbit(x))Tr.Insert(Tr.root[x],v);
}
void Bit_change(int x,int v)
{for(;x<=n+10;x+=lowbit(x))Tr.Del(Tr.root[x],v);
}
void Bit_query(int x,int num)
{for(;x;x-=lowbit(x))Tr.Find(Tr.root[x],num);
}
//////树状数组
struct Bit
{int a[400005];int lowbit(int x){return x&(-x);}int query(int x){int ans = 0;for(;x;x-=lowbit(x))ans+=a[x];return ans;}void updata(int x,int v){for(;x<400005;x+=lowbit(x))a[x]+=v;}
}bit,bit2;///
int main()
{//freopen("a+b.in","r",stdin);
    srand(time(NULL));while(scanf("%d%d",&n,&m)!=EOF){memset(bit2.a,0,sizeof(bit2.a));Tr.init();memset(bit.a,0,sizeof(bit.a));long long Res = 0;for(int i=1;i<=n;i++){a[i]=read();Bit_updata(i,a[i]);bit.updata(a[i],1);Res += (i-bit.query(a[i]-1)-1);pos[a[i]]=i;}memset(bit.a,0,sizeof(bit.a));for(int i=1;i<=n;i++)bit.updata(i,1),bit2.updata(i,1);for(int i=1;i<=m;i++){printf("%lld\n",Res);int x;scanf("%d",&x);long long ans1 = bit2.query(x)-1;//总共有多少数比他小Bit_query(pos[x],x);long long ans2 = tmp;tmp=0;ans2--;//在他前面有多少比他小long long ans3 = bit.query(pos[x])-1;//在他前面一共有多少个数long long Ans1 = ans3 - ans2;//前面有多少个数比他大long long Ans2 = ans1 - ans2;//后面有多少个数比他小//cout<<ans1<<" "<<ans2<<" "<<ans3<<endl;//cout<<Ans1<<" "<<Ans2<<endl;Res = Res-Ans1-Ans2;Bit_change(pos[x],x);bit2.updata(x,-1);bit.updata(pos[x],-1);}}
}

UVA 11990 ``Dynamic'' Inversion 动态逆序对相关推荐

  1. P3157 [CQOI2011]动态逆序对 (CDQ解决三维偏序问题)

    P3157 [CQOI2011]动态逆序对 题目描述 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的任 ...

  2. 【Luogu1393】动态逆序对(CDQ分治)

    [Luogu1393]动态逆序对(CDQ分治) 题面 题目描述 对于给定的一段正整数序列,我们定义它的逆序对的个数为序列中ai>aj且i < j的有序对(i,j)的个数.你需要计算出一个序 ...

  3. HYSBZ - 3295  动态逆序对 (cdq分治)

    F - 动态逆序对 HYSBZ - 3295 题目大意:给出一个序列有m个询问,每一个询问要求输出当前的逆序对数量后在原序列中删除该数字. 解题思路:如果将删除倒着做就变成了插入.没插入一个数字我们就 ...

  4. [Luogu P3157][CQOI2011]动态逆序对 (树套树)

    题面 传送门:[CQOI2011]动态逆序对 Solution 一开始我看到pty巨神写这套题的时候,第一眼还以为是个SB题:这不直接开倒车线段树统计就完成了吗? 然后冷静思考了一分钟,猛然发现单纯的 ...

  5. P3157 动态逆序对 ,树状数组套动态开点线段树

    题目 洛谷题目链接 题解 在求整体的逆序对的数量时,很好办,直接用树状数组处理即可,不过在这时,我们还需要处理出一个数组pa[]pa[]pa[],其中pa[i]pa[i]pa[i]代表在区间[1,i) ...

  6. 【bzoj3295】动态逆序对

    我怎么控制不住自己又写了个数据结构啊--真是的-- 其实我是想练CDQ分治的--结果忍不住又写了个主席树. 首先看看不动态的逆序对咋做?树状数组嘛. 那么删除咋搞?就是考虑贡献,把它前面比他大的,后面 ...

  7. bzoj3295:[CQOI2011]动态逆序对

    传送门 线段树套线段树会TLE+MLE! 树状数组不仅空间小,常数也小(我写的除外) 思考一下求逆序对需要的条件,树套树就过了 代码: #include<cstdio> #include& ...

  8. uva11990 动态逆序对

    这题说的是给了一个数组,按照他给的顺序依次删除数,在删除之前输出此时的逆序对个数 我们用Fenwick树 维护这整个数列, C[i]是一个 treap的头, 管理了在树状数组中 能影响他的点,然后我们 ...

  9. 洛谷 P3157 [CQOI2011]动态逆序对 | CDQ分治

    题目:https://www.luogu.org/problemnew/show/3157 题解: 1.对于静态的逆序对可以用树状数组做 2.我们为了方便可以把删除当成增加,可以化动为静 3.找到三维 ...

最新文章

  1. Android之如何以最简单方式开启闪光灯
  2. 在 Windows 下安装 Oracle 11g XE (Express Edition)
  3. IOC AOP 设计模式
  4. 美团下一代服务治理系统 OCTO 2.0 的探索与实践
  5. 快速开发工作流_01_简单流程案例
  6. 报告一个IE很奇葩的滚动条问题——百分比计算宽度为浮点数时的滚动条显示异常
  7. 【转】灵活运用 SQL SERVER FOR XML PATH
  8. 还在痴迷于大数据?未来 “小数据” 会让你大开眼界
  9. LeetCode(15)3Sum
  10. module ‘cv2‘ has no attribute ‘SIFT‘
  11. 最新USDT支付系统+支持ERC20/OMNI/代理商/第三方API
  12. MySQL 表空间碎片
  13. background 组合写法_css中background复合属性详解
  14. 切线法(牛顿法)、割线法、抛物线法
  15. 【毕业设计】酒店评价情感倾向分析系统 - python 深度学习
  16. 数字化转型对企业的意义
  17. C/C++指针的经典笔试面试题
  18. Mathematics English Vocabulary (Cited)
  19. iphone 打开safari调试
  20. 阿里云短信申请流程以及配置

热门文章

  1. 超强图文|并发编程【等待/通知机制】就是这个feel~
  2. 面试季,Java中的static关键字解析
  3. PostgreSQL专题
  4. Google Scholar公司科研实力大比拼:谷歌1161,华为110,为何差10倍?
  5. 211高校神级硕士论文刷屏!75行字错了20行!学校回应:导师停招
  6. DeepMind一键三连,强推「地鼠」语言模型!只要2800亿参数就能刷SOTA
  7. 世界最大的多语言语音数据集现已开源!超40万小时,共23种语言
  8. 详解Pytorch的nn.DataParallel
  9. 泰晤士最新排名出炉,这两所大学跌惨了
  10. 时间为什么用 12 进制?