hdu5497删除一个序列的连续m个数使得逆序对数最少
来源:互联网 发布:ubuntu chrome 闪烁 编辑:程序博客网 时间:2024/06/17 20:22
题解:
gi表示在i前面比ai大的数的个数, fi表示在i后面比ai小的数的个数, 这两个都可以用树状数组轻松求出来. 那么对于一个长度L的连续子序列, 删掉它之后逆序对减少的个数就是这段区间中gi的和 + 这段区间fi的和 - 这段区间的逆序对个数. 求区间逆序对个数只要用一个树状数组维护就好了, 每次只是删除最左端的一个数和加入最右端的一个数, 分别统计下贡献.
表示本渣渣只会用树状数组求逆序对,而且认识不够深刻,只记得求逆序对要一边插入一边求和,于是乎这题下面那个循环就迷茫了,想了很久才想明白,
b数组就是正常的求逆序对的方法,不多说,c数组这里之前是已经存好的,这里用c数组统计的是在a[i]的后面且比a[i]大的数,
记住这里每次求和之后都从c数组中删除这个点,所以求和的时候统计的一定是在这个数前面且比这个数小的数,b数组即用来统计在这个数后面且比这个数小的数
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <map>#include <set>#include<cmath>#include<climits>#include<vector>#include<cfloat>#include<queue>#include<cctype>#include<cstdlib>#define LL long longusing namespace std;const int N=1e5+10;int a[N],b[N],c[N];int n,m;int lowbit(int x){ return x&(-x);}void update(int *b,int i,int val){ while(i<=n) { b[i]+=val; i+=lowbit(i); }}int sum(int *b,int i){ int ret=0; while(i>0) { ret+=b[i]; i-=lowbit(i); } return ret;}int read(){ int c,x; while(c=getchar(),!isdigit(c)); x=c-'0'; while(c=getchar(),isdigit(c)) x=x*10+c-'0'; return x;}int main(){ int t; t=read(); while(t--) { n=read();m=read(); for(int i=1;i<=n;i++) a[i]=read(); memset(c,0,sizeof(c)); memset(b,0,sizeof(b)); LL tmp=0; for(int i=n;i>m;i--) { tmp+=sum(c,a[i]-1); update(c,a[i],1); } LL ans=tmp; for(int i=m+1;i<=n;i++) { tmp-=sum(c,a[i]-1); tmp-=sum(b,n)-sum(b,a[i]); update(c,a[i],-1); tmp+=sum(c,a[i-m]-1); tmp+=sum(b,n)-sum(b,a[i-m]); update(b,a[i-m],1); ans=min(ans,tmp); } printf("%I64d\n",ans); } return 0;}
0 0
- hdu5497删除一个序列的连续m个数使得逆序对数最少
- 求一个环内连续m个数的最大和
- 找逆序的对数&&和为n的两个数字&&和为n的连续正数序列
- POJ 2299 Ultra-QuickSort (求序列的逆序对数)
- 逆序对数的计算
- 输入一个字符串,删除个数最少的字符 , 如输入abbcc 输出bbcc
- 连续的正数序列,使得和为指定值
- 给一个正整数 n, 找到若干个完全平方数(比如1, 4, 9, ... )使得他们的和等于 n。你需要让平方数的个数最少。
- 给一个正整数 n, 找到若干个完全平方数(比如1, 4, 9, ... )使得他们的和等于 n。你需要让平方数的个数最少。
- POJ 1065 贪心 最少的上升子序列个数
- 最少拦截系统 下降子序列的个数
- 分治法 求 逆序对数 的个数 时间复杂度为O(n*logn)
- 给定一个字符串s,你可以从中删除一些字符,使得剩下的串是一个回文串。如何删除才能使得回文串最长呢? 输出需要删除的字符个数。
- 给定一个字符串a,你可以从中删除一些字符,使得剩下的串是一个回文串。如何删除才能使得回文串最长? 输出需要删除的字符个数。
- 腾讯 2017 暑假实习生编程题(一):给定一个字符串s,你可以从中删除一些字符,使得剩下的串是一个回文串。如何删除才能使得回文串最长呢? 输出需要删除的字符个数。
- 求逆序数的对数
- 求数组的逆序对数
- 删除字符串中字符个数最少的字符
- 切割图片
- CSS动画学习
- C++使函数返回数组
- LintCode-主元素
- iOS编程------UILabel
- hdu5497删除一个序列的连续m个数使得逆序对数最少
- 学习笔记:Html浮动元素的定位
- hive启动报错: Found class jline.Terminal, but interface was expected
- 51nod 1084 更难的矩阵取数问题(DP)
- Matlab-vision包学习-Feature Detection,Extraction and Matching-MSER特征提取
- FreeSWITCH安装报错“You must install libyuv-dev to build mod_fsv”的解决方案
- IOS文章导航
- 一道类加载相关的题目
- UI课程14 标签视图控制器 UITabBarController