zoukankan      html  css  js  c++  java
  • 关于分块和莫队

    关于分块, 我认为没有什么可说的, 只需要背会模板,看情况拓展即可。 而关于莫队, 请参考以下博客:某大佬博客
    和分块一样,莫队是一种偏暴力的算法,很可能会遇到卡常等问题,一下介绍两个没有本质作用的优化。

    1.分块大小

    image
    带修莫队时:
    image
    但这些分块大小遇到P1903 [国家集训队]数颜色 / 维护队列这道题通通TLE, 而我把块的大小定义成一个常数2021时, 发现程序跑的飞快, 64→100,所以当遇到卡常时不妨换个块的大小,说不定有奇迹发生

    2.奇偶性排序

    在排序时,我们还可以加入一个奇偶性的排序优化,对于正常的排序,应该是这样的:

    inline bool compare(query p1,query p2)
    {
    	if ( (p1.l/size) ^ (p2.l/size) )
    	return p1.l < p2.l ;
    	else return p1.r < p2.r;
    }
    

    考虑到左端点在同一块中,我们是按右端点升序排序的,显然在做完一块的所有左端点后,区间的右端点也被移到了整个序列的后方,
    而在下一个块的开始,右端点又是从小到大排序的,这样右端点就要从序列的较后方跑到序列的较前方,这样是很费时间的。

    所以我们考虑排序时将第二关键字右端点的排序方式按照块的奇偶性来决定,也就是说,右端点一次升序一次降序,轮流来,就减少了上述的耗时移动。

    inline bool compare(query p1,query p2)
    {
    	if ( (p1.l/size) ^ (p2.l/size) )
    	return p1.l < p2.l ;
    	else if ( (p1.l/size) & 1 )
    	return p1.r < p2.r ;
    	else return p1.r > p2.r ;
    }
    

    理论上,这种排序方法是有1/2的小常数的。

    3.玄学优化

    这个就靠仙术和自己的运气了,

    //		while (R > r) add(++r);
    //		while (L < l) add(--l);
    //		while (R < r) del(r--);
    //		while (L > l) del(l++);
    		while(l < L) w -= !--cnt[a[l++]];
    		while(l > L) w += !cnt[a[--l]]++;
    		while(r < R) w += !cnt[a[++r]]++;
    		while(r > R) w -= !--cnt[a[r--]];
    

    将函数简化是一种很不错的方法
    以及inline, register, 必要时吸一波氧气:#pragma GCC optimize(2)嘤嘤嘤

  • 相关阅读:
    使用PLSql连接Oracle时报错ORA-12541: TNS: 无监听程序
    算法7-4:宽度优先搜索
    R语言字符串函数
    notepad++ 正则表达式
    MySQL常用命令
    linux下对符合条件的文件大小做汇总统计的简单命令
    Linux系统下统计目录及其子目录文件个数
    R: count number of distinct values in a vector
    ggplot2 demo
    R programming, In ks.test(x, y) : p-value will be approximate in the presence of ties
  • 原文地址:https://www.cnblogs.com/AK-ls/p/15267856.html
Copyright © 2011-2022 走看看