Problem Description
You have a sequence {a1,a2,...,an} and
you can delete a contiguous subsequence of length m.
So what is the minimum number of inversions after the deletion.
 

Input
There are multiple test cases. The first line of input contains an integer T,
indicating the number of test cases. For each test case:

The first line contains two integers n,m(1≤n≤105,1≤m<n) -
the length of the seuqence. The second line contains n integers a1,a2,...,an(1≤ai≤n).

The sum of n in
the test cases will not exceed 2×106.
 

Output
For each test case, output the minimum number of inversions.
 

Sample Input

2
3 1
1 2 3
4 2
4 1 3 2
 

Sample Output

0

1

这场bc的题解虽然很难懂,但是弄明白后觉得写的很好。

令g_ig​i​​表示在ii前面比a_ia​i​​大的数的个数, f_if​i​​表示在ii后面比a_ia​i​​小的数的个数, 这两个都可以用树状数组轻松求出来. 那么对于一个长度LL的连续子序列, 删掉它之后逆序对减少的个数就是这段区间中g_ig​i​​的和 + 这段区间f_if​i​​的和 - 这段区间的逆序对个数. 求区间逆序对个数只要用一个树状数组维护就好了, 每次只是删除最左端的一个数和加入最右端的一个数, 分别统计下贡献.

这里删除一段区间而少的逆序对其实就是区间左边每个数比区间大的数的和以及区间右边比区间内部小的数的个数和,还有区间本身的逆序对。

这里用树状数组的时候要注意,不要总是更新到maxn ,更新到n就行了,不然会超时。

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<string>
#include<algorithm>
using namespace std;
#define ll long long
#define inf 0x7fffffff
#define maxn 100100
ll sum1[maxn],sum2[maxn];
ll b[maxn+10],f[maxn],g[maxn],a1[maxn],a[maxn];
int n; ll lowbit(ll x){
return x&(-x);
} void update(ll pos,ll num){
while(pos<=n){
b[pos]+=num;pos+=lowbit(pos);
}
}
ll getsum(ll pos){
ll num=0;
while(pos>0){
num+=b[pos];pos-=lowbit(pos);
}
return num;
}
void clear(){
int i;
for(i=1;i<=n+1;i++)b[i]=0;
} int main()
{
int m,i,j,T,tot;
ll ans,cnt;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++){
scanf("%lld",&a[i]);
} clear();
sum1[0]=sum2[n+1]=0;
for(i=1;i<=n;i++){
g[i]=getsum(n)-getsum(a[i]);
update(a[i],1);
sum1[i]=sum1[i-1]+g[i];
}
clear();
for(i=n;i>=1;i--){
f[i]=getsum(a[i]-1);
update(a[i],1);
}
for(i=1;i<=n;i++)sum2[i]=sum2[i-1]+f[i]; clear();
cnt=ans=0;
for(i=m;i>=1;i--){
ans+=getsum(a[i]-1);
update(a[i],1);
}
cnt=sum1[m]+sum2[m]-ans;
for(i=2;i+m-1<=n;i++){
ans-=getsum(a[i-1]-1);
update(a[i-1],-1);
ans+=getsum(n)-getsum(a[i+m-1]);
update(a[i+m-1],1);
if(cnt<sum1[i+m-1]-sum1[i-1]+sum2[i+m-1]-sum2[i-1]-ans){
cnt=sum1[i+m-1]-sum1[i-1]+sum2[i+m-1]-sum2[i-1]-ans;
}
}
printf("%lld\n",sum2[n]-cnt); }
return 0;
}

hdu5497 Inversion的更多相关文章

  1. hdu-5497 Inversion(滑动窗口+树状数组)

    题目链接: Inversion Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)T ...

  2. HDU 1394 Minimum Inversion Number ( 树状数组求逆序数 )

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394 Minimum Inversion Number                         ...

  3. 控制反转Inversion of Control (IoC) 与 依赖注入Dependency Injection (DI)

    控制反转和依赖注入 控制反转和依赖注入是两个密不可分的方法用来分离你应用程序中的依赖性.控制反转Inversion of Control (IoC) 意味着一个对象不会新创建一个对象并依赖着它来完成工 ...

  4. HDU 1394 Minimum Inversion Number(最小逆序数 线段树)

    Minimum Inversion Number [题目链接]Minimum Inversion Number [题目类型]最小逆序数 线段树 &题意: 求一个数列经过n次变换得到的数列其中的 ...

  5. 依赖倒置原则(Dependency Inversion Principle)

    很多软件工程师都多少在处理 "Bad Design"时有一些痛苦的经历.如果发现这些 "Bad Design" 的始作俑者就是我们自己时,那感觉就更糟糕了.那么 ...

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

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

  7. Inversion Sequence(csu 1555)

    Description For sequence i1, i2, i3, … , iN, we set aj to be the number of members in the sequence w ...

  8. ACM: 强化训练-Inversion Sequence-线段树 or STL·vector

    Inversion Sequence Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%lld & %llu D ...

  9. ACM Minimum Inversion Number 解题报告 -线段树

    C - Minimum Inversion Number Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d &a ...

随机推荐

  1. 一些JavaSE学习过程中的思路整理(主观性强,持续更新中...)

    目录 一些JavaSE学习过程中的思路整理(主观性强,持续更新中...) Java书写规范 IDEA的一些常用快捷键 Java类中作为成员变量的类 Java源文件中只能有一个public类 Java中 ...

  2. 【Docker】在Linux系统中安装Docker虚拟机、启动停止重启查看Docker命令

    安装Docker 文章目录 安装Docker Docker虚拟机架构 在Linux系统中安装Docker虚拟机 管理Docker虚拟机 参考资料 Docker虚拟机架构 Docker创建的所有虚拟实例 ...

  3. 【Linux】一个网卡部署多个内网ip

    1.用root权限的用户登录CENTOS,进入network-scripts文件夹下(本步骤可以省略,与二步骤一起完成): shell命令:cd /ect/sysconfig/network-scri ...

  4. 【Linux】NFS搭建及使用详解

    环境:CentOS release 6.8 server  192.168.25.100 client1 192.168.25.101 client2 192.168.25.102 1.服务端操作 1 ...

  5. centos7安装宝塔面板

    在终端下执行如下命令 yum install -y wget && wget -O install.sh http://download.bt.cn/install/install.s ...

  6. kafka项目经验之如何进行Kafka压力测试、如何计算Kafka分区数、如何确定Kaftka集群机器数量

    @ 目录 Kafka压测 Kafka Producer(生产)压力测试 Kafka Consumer(消费)压力测试 计算Kafka分区数 Kafka机器数量计算 Kafka压测 用Kafka官方自带 ...

  7. codeup 1934 查找元素

    题目描述: 输入一个数n,然后输入n个数值各不相同,再输入一个值x,输出这个值在这个数组中的下标(从0开始,若不在数组中则输出-1. 输入: 测试数据有多组,输入n(1<=n<=200), ...

  8. 在vCenter Server中添加ESXi 主机失败的问题

    报错:出现了常规系统错误: Timed out waiting for vpxa to start 报错是这个,我看了下vcenter的版本是6.5,如图右上,这个报错是因为我ESXI主机是6.7的, ...

  9. (001)每日SQL学习:关于UNION的使用

    union内部必须有相同的列或者相同的数据类型,同时,每条 SELECT 语句中的列的顺序必须相同.union合并了select的结果集. union 与union all的不同: union合并了重 ...

  10. Springboot中PropertySource注解的使用

    https://blog.csdn.net/qq_30739519/article/list/3 注解 https://blog.csdn.net/qq_30739519/article/detail ...