hdu5273 n次查询求逆序数对
2015-06-20 22:27
260 查看
题目大意:给定一个数组a,输入q次查询(如b,c),输出从a[b] 到a[c] 从在多少逆序数对
N只有1000,刚开始居然n^3,一直没想到,就在那里推一维数组,二维的闪现了一下但是忽略了。 仔细一想发现可以很简单地做到N2. 设dp[l][r]表示从l~r的逆序对数量。首先我们暴力地先算好dp[1][1..N]。 然后i从2∼N枚举,每次计算从i开始的逆序对。 那么dp[i][j]比dp[i-1][j]少了什么呢?没错,少了a[i−1]这个数的贡献。 我们再开一个累加器cnt。枚举j从i∼N,如果a[i-1]和a[j]构成逆序数,则cnt--; 最后dp[i][j]=dp[i−1][j]+cnt[j]。 预处理完所有的答案就可以O(1)的询问啦
#include <iostream> #include <cstring> #include <cstdio> #include <cmath> #include <algorithm> using namespace std; int dp[1005][1005]; int a[1005]; int cnt[1005]; int main() { int N , Q; while(scanf("%d%d" , &N , &Q)!= EOF) { for(int i = 1 ; i <= N ; i ++ ) scanf("%d", &a[i]); memset(dp,0,sizeof(0)); for(int i = 1 ; i <= N ; i ++ ) { for(int j = 1 ; j < i ; j ++ ) { if(a[i] < a[j]) dp[1][i] ++ ; } dp[1][i] += dp[1][i-1]; } for(int i = 2 ; i <= N ; i ++ ) { int ans = 0; for(int j = i ; j <= N ; j ++ ) { if(a[i - 1] > a[j]) ans -= 1 ; dp[i][j] = dp[i-1][j] + ans; } } for(int i = 0 ; i < Q ; i ++ ) { int b , c; scanf("%d%d", &b , &c); printf("%d\n" , dp[b][c]); } } return 0; }[/code]
相关文章推荐
- Windows读取文本文件后的显示过程
- Java初涉之1--Java中的 "+"
- DayDayUP_Linux运维学习_c.vim插件安装和使用
- java基础—System类的方法演示
- BestCoder Round #45
- 【整、借、学、变】四字谈起
- java学习之字符串(上)
- 自己实现基于key-value的NoSQL数据库(三)—— B+树和Hash算法
- 现代魔法:久坐1小时减寿60分钟...
- myeclipse5.5.1 GA开发工具注册码
- hdu1025整合此题网络解题思路
- 当才华配不上梦想,那就静心反思和修炼吧!
- apt-get dpkg 流程
- [BZOJ3926]ZJOI2015诸神眷顾的幻想乡|后缀自动机
- 程序员的量化交易之路(37)--Lean之DataStream数据流5
- 循环赛事日程表
- Cocos2d-3.x_在Lua中使用cjson库解析json
- JSBinding + SharpKit / Home
- SGU 134 Centroid 找树的重心 水题
- 生成1~n的排列,以及生成可重集的排列