很久以前傻乎乎地看来源奇怪的资料的时候被各种曼哈顿弄晕了。

然后现在学会的是分块方法。另新创一个分块方法。

让我们考虑这样一个区间询问问题……

它有如下的性质:

0,n个数,Q个询问。

1,它没有修改操作,这意味着我们可以按我们喜欢的次序跟询问玩耍。实际上后面会讲到我们完全可以按任意次序玩耍。

2,如果我们知道区间询问 [L , R] 对应的值,我们可以轻易求出 [L±1 , R] 和 [L , R±1] 的值。

(其实如果限制增加,比如只能求 [L+1 , R] 和 [L , R-1] 的值,同样不影响问题的解决,——这是我口胡的,没写过,日后再说。我不知道在传统莫队中是怎样的,在新算法中可行。)

3,若2中操作对应复杂度为P,而你需要用O(P*n^1.5)(明明是)O(P*n*Q^0.5)的复杂度来解决问题,那么莫队算法就是你需要的了。

离线方法:将n个数分成sqrt(n)块(一堆这么说的人什么心态)sqrt(Q)块
询问按区间排序,以L所在块序号为第一关键字,R为第二关键字,进行排序。(传统莫队就是如此搞法,YY一下就好了)

不过不知道这个做法怎么流传开的,感觉毫无优点吗……尤其是复杂度这么误导真的好吗。

大部分此类区间题Q总是大于N的(大很多!……)。然后正确的曼哈顿树求法最坏是n*sqrt(m),分块也可以做到这个复杂度,但无脑分块直接成了m*sqrt(n)……

总有一天要出摸你赛把你们卡光光……

(

  但是话说回来……随机数据里sqrt(n)块好像还要快一点……

  随机数据里明显是把块弄得越大越好吗……

)

先说【SPOJ3267:D-query】,毕竟是要做这道才会的。

不过能想用莫队A这题的也不多。

题目描述

有一个n个整数的数列a1,a2,a3,···,an。现有q次查询,每次询问会给出两个数i,j。请你给出在数列的第i个数到第j个数的区间内有多少个不同的数。

输入

第一行:一个整数n,表示数列的长度。

第二行:n个整数a1,a2,a3,···,an(1 <= ai <= 10^6),数与数之间用一个空格隔开。

第三行:一个整数q(<= 200000),表示询问的次数。

接下来q行,每行两个整数i,j(1 <= i <= j <= n <= 30000),表示要询问的区间。

输出

对于每一询问,输出在这个区间内不同的数字个数。

样例输入

5
1 1 2 1 3
3
1 5
2 4
3 5

样例输出

3
2
3

无特别。

#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
#define rep(i,j,n) for(int i=j;i<=n;i++)
char c;template<class T> inline void read(T&x){for(c=getchar();c<'0'||c>'9';c=getchar());for(x=0;c>='0'&&c<='9';c=getchar())x=x*10+c-'0';};
struct E{int x,y,l,list;}d[200010];
int next[30010],prev[30010],p[1000010],ans[200010];
int n,nn,x,T;
bool cmp(E x,E y){return x.l<y.l||(x.l==y.l&&x.y<y.y);}
int main(){
    read(n);memset(next,63,n<<2);
    rep(i,1,n){
        read(x);if(!p[x])p[x]=i;else prev[i]=p[x],next[p[x]]=i,p[x]=i;
    }
    read(T);nn=int(sqrt(n));//块长……理论上的话……改成n/sqrt(m)比较好
    rep(i,1,T){read(d[i].x);read(d[i].y);d[i].l=(d[i].x+nn-1)/nn;d[i].list=i;}
    sort(d+1,d+T+1,cmp);
    int ll,lr,now;
    rep(ii,1,T){
        if(d[ii].l!=d[ii-1].l){
            now=0;
            rep(i,d[ii].x,d[ii].y) if(prev[i]<d[ii].x) now++;
            ans[d[ii].list]=now;
        }else{
            if(d[ii-1].x<d[ii].x){
                ll=d[ii-1].x;lr=d[ii].x-1;
                rep(i,ll,lr) if(next[i]>d[ii-1].y) now--;
            }else{
                ll=d[ii].x;lr=d[ii-1].x-1;
                rep(i,ll,lr) if(next[i]>d[ii-1].y) now++;
            }
            ll=d[ii-1].y+1;lr=d[ii].y;
            rep(i,ll,lr) if(prev[i]<d[ii].x) now++;
            ans[d[ii].list]=now;
        }
    }
    rep(i,1,T) printf("%d\n",ans[i]);
}
 
这个还是传统的分块莫队……新算法放下一篇讲吧。

莫队算法学习笔记【BZOJ2038:小Z的袜子】【SPOJ3267:D-query】的更多相关文章

  1. 【序列莫队】BZOJ2038- [2009国家集训队]小Z的袜子(hose)

    [题目大意]给出1-N只袜子的颜色,多次询问L-R中选出一双同色袜子的概率. [思路] 裸莫队.基本的莫队步骤:①分组(每组大小为根号sqrt(n),共sqrt(n)组)②排序(左边界分组,右边界在组 ...

  2. E. XOR and Favorite Number 莫队 2038: [2009国家集训队]小Z的袜子(hose)

    一直都说学莫队,直到现在才学,训练的时候就跪了   T_T,其实挺简单的感觉.其实训练的时候也看懂了,一知半解,就想着先敲.(其实这样是不好的,应该弄懂再敲,以后要养成这个习惯) 前缀异或也很快想出来 ...

  3. BZOJ2038 小Z的袜子 (莫队算法)

    题目链接: http://www.lydsy.com/JudgeOnline/problem.php?id=2038 专题练习: http://acm.hust.edu.cn/vjudge/conte ...

  4. BZOJ-2038 小Z的袜子(hose) 莫队算法

    2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec Memory Limit: 259 MB Submit: 5573 Solved: 2568 [Subm ...

  5. [BZOJ2038]小Z的袜子(莫队算法)

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2038 分析:莫队算法 莫队算法是一种思想…… 处理问题:不带修改的区间询问 使用要求:[l-1 ...

  6. bzoj2038 小Z的袜子(hose)——莫队算法

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2038 就是莫队算法: 先写了个分块,惨WA: #include<iostream> ...

  7. 洛谷 P1972 [SDOI2009]HH的项链【莫队算法学习】

    P1972 [SDOI2009]HH的项链 题目背景 无 题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含 ...

  8. BZOJ2038小Z的袜子(hose)

    2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 2343  Solved: 1077[Subm ...

  9. Bzoj2038 小Z的袜子(hose)

    Time Limit: 20000MS   Memory Limit: 265216KB   64bit IO Format: %lld & %llu Description 作为一个生活散漫 ...

随机推荐

  1. 一个使用CSocket类的网络通信实例

    http://www.cppblog.com/changshoumeng/archive/2010/05/14/115413.html 3.8 一个使用CSocket类的网络通信实例 本例采用CSoc ...

  2. Pycharm在创建py文件时,如何自动添加文件头注释(类似于钩子特性)?

    在每次新建一个py文件的时候 1 如何自动添加/usr/bin/env python2 自动添加 coding=utf8 操作方法: File->settings->Editor-> ...

  3. 文件操作类CFile

    CFile file; CString str1= L"写入文件成功!"; wchar_t *str2; if (!file.Open(L"Hello.txt" ...

  4. Mongodb增加权限管理

     前言: 随着列式存储理念的成熟,越来越多的开发者开始接纳mongodb,hbase这类大储存的分布式列式数据库.特别是mongodb的这种快速搭建,快速使用特点,使其得到更多人的青睐.本人主要通过官 ...

  5. noi 04:网线主管

    04:网线主管 查看 提交 统计 提问 总时间限制:  1000ms 内存限制:  65536kB 描述 仙境的居民们决定举办一场程序设计区域赛.裁判委员会完全由自愿组成,他们承诺要组织一次史上最公正 ...

  6. C#数据类型汇总

    通用类型系统 C#中,变量是值还是引用仅取决于数据类型 所有的数据类型都是对象.因为它们具有自己ide方法和属性 int int_value = 101; //调用*int_value*的比较方法与整 ...

  7. php5,Apache在windows 7环境搭建

    主要是参考以下文章: http://www.cnblogs.com/Yogurshine/archive/2013/05/24/3097343.html http://jingyan.baidu.co ...

  8. 通过并行 提高批量审核PDF性能

    上一篇文章提到了 通过 iTextSharp 实现PDF 审核盖章 ,如果当需要一次审核大批量的PDF我们如何来提高程序的性能呢? 下面我们通过并行计算来提升性能. 首先是一个审核PDF的方法 pub ...

  9. USACO6.4-Wisconsin Squares:搜索

    Wisconsin Squares It's spring in Wisconsin and time to move the yearling calves to the yearling past ...

  10. fzu1759:数论高次幂降幂

    题目大意: 求 a^b mod c的值..但是b会非常大(10^1000000) 所以需要用到一个数论公式: A^x = A^(x % Phi(C) + Phi(C)) (mod C) 证明见ac大神 ...