赛时一小时,赛后十分钟。

题意:给定一个序列 \(a\) 和一个集合 \(b\),问将 \(b\) 中所有元素插入 \(a\) 后逆序对最少是多少。

观察样例解释,发现 \(b\) 已经被排序过了,于是就猜想一个结论:

设排序后 \(b_i\) 在 \(x_i-1\) 和 \(x_i\) 之间被插入,那么对于 \(i<j\) 时一定有 \(x_i \leq x_j\)。

证明:邻项交换,假如交换两个相邻元素,相当于令 \(b_i\) 变大,\(b_j\) 变小,这样一来 \(x_i\) 右边的元素对 \(b_i\) 的贡献就变大了,\(x_j\) 左边的元素同理。

于是将 \(b\) 排序后依次插入 \(a\)。考虑在线地插入 \(b\)。那么对于 \(a\) 上的每一个位置得维护当前左边比该元素大的个数和当前右边比该元素小的个数。

由于已经将 \(b\) 排序了,所以可以考虑维护 \(s_i\) 表示 \([1,i)\) 比当前的 \(b\) 大的元素个数与 \([i,n]\) 不大于当前 \(b\) 的元素个数之和。将 \(a\) 也排序即可。

这样就可以动态地统计答案了。

#include<algorithm>
#include<cstdio>
const int M=1e6+5;
int T,n,m,t,a[M],b[M],id[M],mi[M*21];int len,lsh[M<<1];int tim[M*21],tag[M*21];
inline void upd(const int&u,const int&id){
tim[u]^t&&(mi[u]=id-1,tim[u]=t,tag[u]=0);
}
inline void update(const int&u){
mi[u]=mi[u<<1|mi[u<<1]>mi[u<<1|1]];
}
inline void pushdown(const int&u,const int&L,const int&R){
if(!tag[u])return;upd(u<<1,L);upd(u<<1|1,(L+R>>1)+1);
mi[u<<1]+=tag[u];mi[u<<1|1]+=tag[u];tag[u<<1]+=tag[u];tag[u<<1|1]+=tag[u];tag[u]=0;
}
void Modify(const int&u,const int&l,const int&r,const int&val,const int&L=1,const int&R=n+1){
if(upd(u,L),l>R||L>r)return;if(l<=L&&R<=r)return mi[u]+=val,tag[u]+=val,void();pushdown(u,L,R);
int mid=L+R>>1;Modify(u<<1,l,r,val,L,mid);Modify(u<<1|1,l,r,val,mid+1,R);update(u);
}
namespace BIT{
int t,tim[M<<1],sum[M<<1];
inline void Add(int x){
for(;x<=len;x+=x&-x)tim[x]^t&&(sum[x]=0,tim[x]=t),++sum[x];
}
inline int Query(int x){
int ans(0);
for(;x>=1;x-=x&-x)tim[x]^t&&(sum[x]=0,tim[x]=t),ans+=sum[x];
return ans;
}
}
signed main(){
int i,x,y;long long sum;scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);++t;++BIT::t;sum=len=0;x=y=1;
for(i=1;i<=n;++i)scanf("%d",a+i),lsh[++len]=a[id[i]=i];
for(i=1;i<=m;++i)scanf("%d",b+i),lsh[++len]=b[i];std::sort(b+1,b+m+1);
std::sort(id+1,id+n+1,[](const int&x,const int&y){return a[x]<a[y];});
std::sort(lsh+1,lsh+len+1);len=std::unique(lsh+1,lsh+len+1)-lsh-1;
for(i=1;i<=n;++i)a[i]=std::lower_bound(lsh+1,lsh+len+1,a[i])-lsh;
for(i=1;i<=m;++i)b[i]=std::lower_bound(lsh+1,lsh+len+1,b[i])-lsh;
for(i=n;i>=1;--i)sum+=BIT::Query(a[i]-1),BIT::Add(a[i]);mi[1]=0;
for(i=1;i<=m;++i){
while(a[id[x]]<b[i]&&x^n+1)Modify(1,1,id[x++],1);
while(a[id[y]]<=b[i]&&y^n+1)Modify(1,id[y++]+1,n+1,-1);sum+=mi[1];
}
printf("%lld\n",sum);
}
}

CF1601C题解的更多相关文章

  1. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  2. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  3. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  4. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  5. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  6. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  7. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

  8. 网络流n题 题解

    学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...

  9. CF100965C题解..

    求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...

随机推荐

  1. bom-删除提示

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. HTML页元素自适应+居中总结(不定期补充)

    感谢大佬:https://www.cnblogs.com/SallyShan/p/11480685.html 图片自适应 背景图片自适应 /*背景页*/ #page_content{ width: 1 ...

  3. 循环retian

    1.循环retian基本概念 循环retain的场景 比如A对象retain了B对象,B对象retain了A对象 循环retain的弊端 这样会导致A对象和B对象永远无法释放 循环retain的解决方 ...

  4. 增删改查简单的sql语句

    insert INSERT   INTO    t_stu   (name,age)  VALUES  ('wang',12) INSERT INTO    t_stu   VALUES(NULL,' ...

  5. Linux之shell变量

    一.变量名的规范 定义形如:class_name='xiaohemiao' 使用形如:echo $class_name 1.变量名后面的等号左右不能有空格 2.命名只能使用英文字母,数字和下划线,首个 ...

  6. HTTP状态码100、200、300、400、500、600的含义

    1xx (临时响应)表示临时响应并需要请求者继续执行操作的状态代码. 100 (继续) 请求者应当继续提出请求. 服务器返回此代码表示已收到请求的第一部分,正在等待其余部分. 101 (切换协议) 请 ...

  7. windows server2012搭建邮箱服务器+客户端界面(hmailserver+afterlogic)+批量创建邮箱

    1.简介 由于需要较多邮箱,如果去注册需要很多的手机号码去验证,一个人不可能买一堆的手机号,所以自己搭建一个邮箱服务器可以大批量的创建自己的邮箱账号和收发邮件. 2.安装部署hmailserver 下 ...

  8. Linux运维-常用操作-培训用例

    一.服务器环境 Centos 7.9 二.常用连接工具(免费) 1.Finalshell 2.MobaXterm 3.Putty + WinSCP 三.Linux  系统目录结构 /bin :是 Bi ...

  9. JDK中线程中实现同步等待闭环的一种方式

    实际Thread类自带的join方法就实现了线程同步等待,具体可以通过案例实践,如下: 本文的重点不是join,而是另一种设计的同步等待实现,涉及的关键类有:Thread.Runable.Callab ...

  10. .NET 云原生架构师训练营(权限系统 代码重构)--学习笔记

    目录 模块拆分 代码重构 模块拆分 代码重构 AuthenticationController PermissionController IAuthorizationMiddlewareResultH ...