UVA 11990 ``Dynamic'' Inversion 动态逆序对
``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 动态逆序对相关推荐
- P3157 [CQOI2011]动态逆序对 (CDQ解决三维偏序问题)
P3157 [CQOI2011]动态逆序对 题目描述 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的任 ...
- 【Luogu1393】动态逆序对(CDQ分治)
[Luogu1393]动态逆序对(CDQ分治) 题面 题目描述 对于给定的一段正整数序列,我们定义它的逆序对的个数为序列中ai>aj且i < j的有序对(i,j)的个数.你需要计算出一个序 ...
- HYSBZ - 3295 动态逆序对 (cdq分治)
F - 动态逆序对 HYSBZ - 3295 题目大意:给出一个序列有m个询问,每一个询问要求输出当前的逆序对数量后在原序列中删除该数字. 解题思路:如果将删除倒着做就变成了插入.没插入一个数字我们就 ...
- [Luogu P3157][CQOI2011]动态逆序对 (树套树)
题面 传送门:[CQOI2011]动态逆序对 Solution 一开始我看到pty巨神写这套题的时候,第一眼还以为是个SB题:这不直接开倒车线段树统计就完成了吗? 然后冷静思考了一分钟,猛然发现单纯的 ...
- P3157 动态逆序对 ,树状数组套动态开点线段树
题目 洛谷题目链接 题解 在求整体的逆序对的数量时,很好办,直接用树状数组处理即可,不过在这时,我们还需要处理出一个数组pa[]pa[]pa[],其中pa[i]pa[i]pa[i]代表在区间[1,i) ...
- 【bzoj3295】动态逆序对
我怎么控制不住自己又写了个数据结构啊--真是的-- 其实我是想练CDQ分治的--结果忍不住又写了个主席树. 首先看看不动态的逆序对咋做?树状数组嘛. 那么删除咋搞?就是考虑贡献,把它前面比他大的,后面 ...
- bzoj3295:[CQOI2011]动态逆序对
传送门 线段树套线段树会TLE+MLE! 树状数组不仅空间小,常数也小(我写的除外) 思考一下求逆序对需要的条件,树套树就过了 代码: #include<cstdio> #include& ...
- uva11990 动态逆序对
这题说的是给了一个数组,按照他给的顺序依次删除数,在删除之前输出此时的逆序对个数 我们用Fenwick树 维护这整个数列, C[i]是一个 treap的头, 管理了在树状数组中 能影响他的点,然后我们 ...
- 洛谷 P3157 [CQOI2011]动态逆序对 | CDQ分治
题目:https://www.luogu.org/problemnew/show/3157 题解: 1.对于静态的逆序对可以用树状数组做 2.我们为了方便可以把删除当成增加,可以化动为静 3.找到三维 ...
最新文章
- Android之如何以最简单方式开启闪光灯
- 在 Windows 下安装 Oracle 11g XE (Express Edition)
- IOC AOP 设计模式
- 美团下一代服务治理系统 OCTO 2.0 的探索与实践
- 快速开发工作流_01_简单流程案例
- 报告一个IE很奇葩的滚动条问题——百分比计算宽度为浮点数时的滚动条显示异常
- 【转】灵活运用 SQL SERVER FOR XML PATH
- 还在痴迷于大数据?未来 “小数据” 会让你大开眼界
- LeetCode(15)3Sum
- module ‘cv2‘ has no attribute ‘SIFT‘
- 最新USDT支付系统+支持ERC20/OMNI/代理商/第三方API
- MySQL 表空间碎片
- background 组合写法_css中background复合属性详解
- 切线法(牛顿法)、割线法、抛物线法
- 【毕业设计】酒店评价情感倾向分析系统 - python 深度学习
- 数字化转型对企业的意义
- C/C++指针的经典笔试面试题
- Mathematics English Vocabulary (Cited)
- iphone 打开safari调试
- 阿里云短信申请流程以及配置