【题解】[CQOI]动态逆序对
题意如题,维护一个动态序列的逆序对总数。
注意题目给的是\([1,n]\)的排列,所以没必要离散化了。
考虑逆序对:二维偏序可以用树状数组做,现在是三维偏序,即加了一个时间维度。
找一个数前面大于它的数和后面小于它的数,可以想到主席树做。
考虑修改操作,普通主席树的修改是不好做的,在静态前缀和上面修改太累了。
考虑树状数组套动态开点权值线段树。
树状数组维护前缀和即可。
注意的是,修改操作不能只把删的这个值的前后逆序对数减掉,因为这会影响后面数的逆序对个数。所以要在主席树(或者说动态开点权值线段树)上面动态修改,维护正确信息。
#include<bits/stdc++.h>
using namespace std;
const int MAXN=4e5+10;
typedef long long ll;
#define rg register
inline int read(){
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')w=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
s=(s<<1)+(s<<3)+(ch^48);
ch=getchar();
}
return w==-1?-s:s;
}
int a[MAXN],n,m,b[MAXN];
int cur,num[MAXN];
ll res1[MAXN],res2[MAXN];
ll Ans;
namespace SGT{
int rt[MAXN<<2],tot,lc[MAXN<<5],rc[MAXN<<5],sum[MAXN<<5];
void build(int &x){x=++tot;}
void update(int &x,int l,int r,int pos,int v){
if(!x)build(x);
sum[x]+=v;
if(l==r)return;
int mid=l+r>>1;
if(pos<=mid)update(lc[x],l,mid,pos,v);
else update(rc[x],mid+1,r,pos,v);
}
}
using namespace SGT;
inline int lowbit(int x){return x&(-x);}
void upd(int x,int pos,int v){for(;x<=n;x+=lowbit(x))update(rt[x],1,n,pos,v);}
int query1(int r,int x){
int ans=0;
for(rg int i=r;i;i-=lowbit(i)){
int L=1,R=n;
int u=rt[i];
while(sum[u]&&(L^R)){
rg int mid=L+R>>1;mid++;
if(mid>x)ans+=sum[rc[u]],u=lc[u],R=mid-1;
else L=mid,u=rc[u];
}
}
return ans;
}
int query2(int l,int x){
int ans=0;
for(rg int i=l-1;i;i-=lowbit(i)){
int L=1,R=n,u=rt[i];
while(sum[u]&&(L^R)){
rg int mid=L+R>>1;
if(mid<x)ans-=sum[lc[u]],u=rc[u],L=mid+1;
else u=lc[u],R=mid;
}
}
for(rg int i=n;i;i-=lowbit(i)){
int L=1,R=n,u=rt[i];
while(sum[u]&&(L^R)){
rg int mid=L+R>>1;
if(mid<x)ans+=sum[lc[u]],u=rc[u],L=mid+1;
else u=lc[u],R=mid;
}
}
return ans;
}
int main(){
n=read(),m=read();
for(rg int i=1;i<=n;++i)a[i]=read(),num[a[i]]=i;
for(rg int i=1;i<=m;++i)b[i]=read();
for(rg int i=1;i<=n;++i)upd(i,a[i],1);
for(rg int i=1;i<=n;++i){
res1[i]=query1(i-1,a[i]);
res2[i]=query2(i+1,a[i]);
Ans+=res1[i]+res2[i];
}
Ans>>=1;
printf("%lld\n",Ans);
for(rg int i=1;i<m;++i){
upd(num[b[i]],b[i],-1);
Ans-=query1(num[b[i]]-1,b[i]);
Ans-=query2(num[b[i]]+1,b[i]);
printf("%lld\n",Ans);
}
return 0;
}
【题解】[CQOI]动态逆序对的更多相关文章
- 【题解】动态逆序对 [CQOI2011] [P3157] [BZOJ3295] [P1393]
[题解]动态逆序对 [CQOI2011] [P3157] [BZOJ3295] [P1393] 水一水QAQ 题目链接: \([P3157]\) \([BZOJ3295]\) [题目描述] 对于一个序 ...
- 【bzoj3295】[Cqoi2011]动态逆序对
题目描述: 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的任务是在每次删除一个元素之前统计整个序列的逆 ...
- cdq分治(hdu 5618 Jam's problem again[陌上花开]、CQOI 2011 动态逆序对、hdu 4742 Pinball Game、hdu 4456 Crowd、[HEOI2016/TJOI2016]序列、[NOI2007]货币兑换 )
hdu 5618 Jam's problem again #include <bits/stdc++.h> #define MAXN 100010 using namespace std; ...
- Bzoj 3295: [Cqoi2011]动态逆序对 分块,树状数组,逆序对
3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2886 Solved: 924[Submit][Stat ...
- 【Luogu1393】动态逆序对(CDQ分治)
[Luogu1393]动态逆序对(CDQ分治) 题面 题目描述 对于给定的一段正整数序列,我们定义它的逆序对的个数为序列中ai>aj且i < j的有序对(i,j)的个数.你需要计算出一个序 ...
- 【BZOJ3295】动态逆序对(线段树,树状数组)
[BZOJ3295]动态逆序对(线段树,树状数组) 题面 Description 对于序列A,它的逆序对数定义为满足iAj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的 ...
- [BZOJ3295][Cqoi2011]动态逆序对 CDQ分治&树套树
3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec Memory Limit: 128 MB Description 对于序列A,它的逆序对数定义为满足i<j,且 ...
- 洛谷P1393 动态逆序对(CDQ分治)
传送门 题解 听别人说这是洛谷用户的双倍经验啊……然而根本没有感觉到……因为另外的那题我是用树状数组套主席树做的……而且莫名其妙感觉那种方法思路更清晰(虽然码量稍稍大了那么一点点)……感谢Candy大 ...
- 【LG1393】动态逆序对
[LG1393]动态逆序对 题面 洛谷 题解 \(CDQ\)分治,按照时间来分治 应为一个删除不能对前面的操作贡献,所以考虑一个删除操作对它后面时间的操作的贡献 用上一个答案减去次贡献即可 代码 #i ...
随机推荐
- new Map()详细介绍与对比
说明: Map结构提供了“值—值”的对应,是一种更完善的Hash结构实现.如果你需要“键值对”的数据结构,Map比Object更合适.它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串, ...
- 深入理解SVM,软间隔与对偶问题
今天是机器学习专题的第33篇文章,我们继续来聊聊SVM模型. 在上一篇文章当中我们推到了SVM模型在线性可分的问题中的公式推导,我们最后得到的结论是一个带有不等式的二次项: \[\left\{\beg ...
- wxmini
微信小游戏架构概览 https://www.jianshu.com/p/02199c35d749 微信小程序:工具配置 project.config.json https://www.cnblogs. ...
- 为什么 char 数组比 String 更适合存储密码?
推荐阅读:5 个刁钻的 String 面试题! 另一个基于 String 的棘手 Java 问题,相信我只有很少的 Java 程序员可以正确回答这个问题. 这是一个真正艰难的核心 Java 面试问题, ...
- 使用Hint /*+ full(emp)*/ 将索引全扫描改成全表扫描,看cost差别
索引全扫描的执行计划: SQL> select max(age) from tb_emp04 emp; 已用时间: 00: 00: 00.01 执行计划 -------------------- ...
- Eclipse中java文件边的黄色数据库标志变成了蓝色小勾,导致文件修改后无法显示在Git staging窗口中,修改无法提交,怎么解决?
出现这个问题的原因是误点击了右键点文件->Team->Advanced->Assume Unchanged, 导致结果是文件修改了无法显示在Git staging窗口中,自然无法提交 ...
- leetcode刷题-64最小路径和
题目 给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小. 说明:每次只能向下或者向右移动一步. 示例: 输入:[ [1,3,1], [1,5, ...
- roarctf_2019_easy_pwn
这篇博客主要记录当直接在malloc_hook中直接写入one_gadget不起作用时的一些处理方法.题目附件:https://buuoj.cn/challenges#roarctf_2019_eas ...
- Readme for Software engineering
作业任务: 软件工程 软件工程 作业要求 作业要求 作业目标 博客园.github注册 自我介绍 软工5问 自我介绍: 广东工业大学计算机学院18级信息安全二班 广东工业大学AD攻防工作室成员& ...
- 【机器学习】:Kmeans均值聚类算法原理(附带Python代码实现)
这个算法中文名为k均值聚类算法,首先我们在二维的特殊条件下讨论其实现的过程,方便大家理解. 第一步.随机生成质心 由于这是一个无监督学习的算法,因此我们首先在一个二维的坐标轴下随机给定一堆点,并随即给 ...