时间一长居然连归并排序都忘了怎么写了…… 偏偏这玩意还不能用STL,必须手写…… 而且这道题又是递归又是取反又是求和,真心麻烦,费了我一个上午才弄出来……期间还遇上了各种各样的问题。

记录一下归并排序:开数组的时候没什么特殊情况就开在全局变量里,然后tmp数组也可以开在全局变量里,由于栈内存的限制,不要把局部变量开得很大,通常栈内存只有可怜的16MB,稍微奢侈一点就爆了……而且爆的特别坑爹,编译器会随便给你标记一行错了,还不让调试,如果不知道是这个问题的话,一辈子也不可能找到到底是哪错了。

这里稍微多说一句,上次做GCJ Round1A的B题时,已经想到了AC算法,就是大数据死活崩溃,估计就是栈内存的事。

递归层数不能过深其实跟这个是一样的道理,栈内存是他俩一块用的。

解决方法有这么几个:第一个是,当然,要是能开成全局的数组最好,这样就是内存总上限管你了;第二就是如果确认实际要处理的东西没那么多,可以用vector,就不会爆了;第三,可以手动扩大栈内存的量…… 这个是我查到的,还没有试验,不知管不管用

在头文件定义的区域加上一句:

#pragma comment(linker, "/STACK:1024000000,1024000000")

也不知道后面两个数什么意思,看着挺吓人的,不过他们都这么写……

然后说这道题,这道题是说一开始有一个长度为2^n的序列,然后不断地划分,前一半长度的数一组,后一半长度的数一组,然后下一层再划分,成为4组…… 直到化为每组只有一个数;接下来有q个操作,每个操作是把一层的所有组组内的数全部逆序,然后每做一次就会问你当前序列的逆序数是多少。

一开始确实想到了归并排序,毕竟这个结构几乎已经告诉你是归并排序了,问题就在于你不能真的去更新每一层的所有节点,如果他不断更新最后一层,那就变成n平方的了。由于一次是对一层操作,所以只需要给每层记录一个数就好。问题就在于这个数怎么定义,由于把每一层逆序时,所有的顺序对和逆序对都互换了,所以每一层只需要存储这一层的顺序对和逆序对即可。注意顺序对+逆序对不一定是对数的总数,因为两个相等的数既不是顺序对也不是逆序对。

然后另一个关键的问题就是谁更新谁。我一开始以为是向上更新,其实是不对的,应该是向下更新。假设现在有8个数,12345678,下设1234  5678 、 12 34 56 78, 1 2 3 4 5 6 7 8, 现在我要把第二层反向,那么可以理解成之后的全反向,变成4321 8765、 43 21 87 65, 4 3 2 1 8 7 6 5,这样才是正确的。不能只改一层,因为每一层逆序对/顺序对的信息其实是 (左边逆序对的数量) +  (右边逆序对的数量) + 本层逆序对的数量,当你逆转一层的时候,后边的关系也变化了,而对于上面的节点来说,“本层逆序对的数量”是没有变的。(该从左边取还从左边取,右边同样)

然后贴一个归并排序求逆序数的模板

void merge(int s, int mid, int e, int level)
{int i,j;int p=s;i=s;j=mid+1;while(i<=mid && j<=e){if(a[i] <= a[j]){tmp[p] = a[i];i++;p++;}else{layer[level] += mid+1 - i;//只是求当前层的tmp[p] = a[j];j++;p++;}}while(i<=mid){tmp[p] = a[i];i++;p++;}while(j<=e){tmp[p] = a[j];p++;j++;}for(i=s;i<=e;i++)a[i] = tmp[i];
}void merge_sort(int s, int e, int level)
{if(e==s)return;int mid = (s+e) /2;merge_sort(s, mid, level-1);merge_sort(mid+1, e, level-1);merge(s, mid, e, level);
}

反正就是每次merge的时候写tmp的一部分,然后把tmp的这一部分还给a就可以了。

求逆序数的时候,其实就是对于每一个左边的数,看一看右边的数里面有几个比他小的就行。这可以用二分搜索做,由于这道题既要求逆序对又要求顺序对,只靠归并是不行的,所以有的人这么做了,但是我自己写发现这样会超时…… 感觉是NlogNlogN的复杂度,有点悬,最后我是归并了两次,一次求顺序对,一次求逆序对,虽然笨拙了点,但是总算是过了……

ACM练级日志: CodeForces 414C 归并排序、逆序数和栈内存相关推荐

  1. ACM练级日志:HDU 4274

    是挺简单的一道题,但是却无限WA,总共修改了这么几个错误: 第一,每个人都至少要有一块钱工资,比如1号下面有2号,3号,2号有1块钱,3号有一块钱,那么1号至少要有3块钱才行,如果给出条件说1 < ...

  2. ACM练级日志: POJ 2155、1151

    这些日志仅供以后防止自己出现过去犯过的错误,起到一个注记的作用.若其他的ACMer觉得有用的话,本人也感到欣慰~ 最近一直在练线段树,说说线段树的"染色问题"和"计数问题 ...

  3. ACM练级日志:ACM2013 南京网络赛

    这篇日志是用来反省用的-- 本场比赛我们总共A3题,我1题,ztb2题,但是因为我的博弈树搜索卡了,导致我们没能上第四道题,虽然前面三题很顺利,但是这致命的一题还是卡死了我们的队伍. 先说说题吧,10 ...

  4. ACM练级日志:HDU 4433 Locker

    天津现场赛的一道题,说有两个密码串,每次你可以转第一个串连着的最多三个数,问最少转多少次能把第一串转成第二串. 开始以为是搜索,后来一看n<=1000直接吓尿-- 后来以为是字符串,但是怎么做也 ...

  5. ACM练级日志:set

    STL这个东西有时候会出乎意料的好用,第7篇那个让我写了200行的Treap用set这个玩意可以省掉很多代码--所以之后又用set重新写了一遍,正好以前也没用过set,记录一下,万一下次还有呢. se ...

  6. ACM练级日志:Level 3的线段树标记下传

    前几日参加了西山居比赛,里面有一道线段树题,代码量奇大,不过就是稍微变了点花样的标准线段树Lv3题,就是插入删除一些线段,然后问你其中最左边的长度至少为x的线段在哪儿.这道题前天调了2个小时终于AC, ...

  7. ACM练级日志: POJ 1376

    本来是因为另一道题过不去而来找一道搜索题虐一下的,结果自己反而被虐了-- 这是一道很纯粹的BFS寻路题,写的时候因为比较急躁,犯了不少错误.写题的时候还是不能着急啊,尤其是比赛的时候更为紧张,稍微一错 ...

  8. ACM练级日志:微软编程之美比赛测试赛-3(高精度相关)

    微软的这个测试赛也不是那么水,看第一题那个不友好的A+B也就能猜出一二,第三题那个套着高精度的DP是无数NOIP小白的噩梦,包括我在内.不过学习了面向对象程序设计之后似乎对以前处理高精度的方法重新地认 ...

  9. ACM练级日志:POJ 3074 数独与DLX

    各位还在使用百度空间的同学们,请原谅最近被我刷屏-- 数独是DLX建模的最经典应用,它最好地示范了"行=决策,列=约束"的建模方法,配合快速的DLX深搜,使它成为了目前最快的求解数 ...

最新文章

  1. Xshell 6 提示 要继续使用此程序,您必须应用最新的更新
  2. Java内部类(Inner Class)小记
  3. “面试不败计划”:集合总结
  4. 最大权闭合子图(最小割)
  5. LinkedList 方法知识点
  6. 除了数据恢复,EasyRecovery还有这样的功能!
  7. 单元素的枚举类型已经成为实现Singleton的最佳方法
  8. win7下快捷方式关联错误的修复
  9. 【优化系列】VS与YASM的集成使用
  10. 有管网气体消防系统小知识来啦
  11. 英语口语收集(三十七)
  12. go模拟android浏览器,模拟浏览器登录操作
  13. 2017-11-3 白银分析
  14. windows 运行 自定义 命令 的实现
  15. 三星电视618钜惠火热进行中,6月2日总裁直播惊喜“价”到
  16. 物联网时代数据数据库如何选型?
  17. Mysql复制表结构、表数据以及修改主键
  18. CentOS 环境下的一些配置(安装软件)
  19. px、em 和 rem 三者区别
  20. 5月6日—5月9日三年级课程新

热门文章

  1. 一文教你学会实现以邮件激活的注册账户代码
  2. 物联网安全|位置隐私保护方法
  3. 高频Postman软件测试面试题
  4. 牛客——牛妹与牛牛的游戏
  5. 传感器:可穿戴设计配方中的关键成分
  6. vue组件通信---全局事件总线(任意组件间通信)
  7. 武汉大学职称评定认定、计算机类中文核心期刊
  8. js进行搜索数组,实现搜索
  9. 什么耳机适合运动,蓝牙运动耳机推荐
  10. 简洁优雅的Mac OS X软件安装体验 - homebrew-cask