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. 了解一下IO控制器与控制方式

    IO控制器 CPU无法直接控制IO设备的机械部件,因此IO设备还要有个电子部件作为CPU和IO设备机械部件之间的"中介",用于实现CPU对设备的控制. 这个电子部件就是IO控制器, ...

  2. 【Linux】history用法

    通过history命令可以查看我们在系统中输入过的命令 history命令的一些常用参数 -c  清空内存中命令历史 -d #  删除指定的历史命令,比如 history -d 100 ,就是删除第1 ...

  3. kubernets之向外部应用暴露应用

    一  通过NodePort来暴露服务 前面已经介绍的服务的一些作用,例如将集群内部的应用暴露给集群内部的pod使用,将外部的应用通过服务暴露给内部应用使用,但是服务最大的作用不仅仅是这些 而是将集群内 ...

  4. 处理Promise.reject()

    一般处理Promise.reject()都是catch住错误,然后进行错误处理,一般都是再次发起请求或者直接打印. 直接打印的情况用console.error()就可以了,而再次发起请求呢? 最好是先 ...

  5. Java基础复习2

    三目运算符 语法:条件判断?表达式1:表达式2; 如果条件判断成立则获取值1否则获取值2 public class demo1{     public static void main(String[ ...

  6. Flink可靠性的基石-checkpoint机制详细解析

    Checkpoint介绍 checkpoint机制是Flink可靠性的基石,可以保证Flink集群在某个算子因为某些原因(如 异常退出)出现故障时,能够将整个应用流图的状态恢复到故障之前的某一状态,保 ...

  7. 全栈性能测试修炼宝典-JMeter实战笔记(一)

    了解性能测试 性能测试不仅能够定位.分析问题,还要把握系统性能变化趋势:性能测试工程师能够帮助解决性能问题,搞定测试过程中的各种不合理配置,给出专业的优化建议. 第一章 性能方向职业发展 软件测试职业 ...

  8. .net core 不同地区时间相互转换

    .net core 不同地区时间相互转换 //韩国时间转换成当前时间 //value=需要转换的时间 //Korea Standard Tim 韩国时间 //China Standard Time 中 ...

  9. shell命令分隔符 二叉树结构的命令行树

    shell命令分隔符 二叉树结构的命令行树 I  ;&

  10. https://learnku.com/docs/go-blog/qihoo/6532 。 heap size went up to 69G, with maximum garbage collection (GC)

    https://learnku.com/docs/go-blog/qihoo/6532 Use a Task Pool, a mechanism with a group of long-lived ...