码迷,mamicode.com
首页 > 其他好文 > 详细

莫队小结

时间:2017-10-10 00:05:00      阅读:145      评论:0      收藏:0      [点我收藏+]

标签:sed   应该   多少   等等   logs   技术   应用   isp   强制   

最近刚刚学习了莫队算法,感觉很神奇,很强大,于是我打算写一些小小的总结,希望能对看的人有一点点帮助。ps:noip前我是不会学新算法啦qwq...老师让我多刷刷题连连代码能力

对于莫队算法,我们可以简单的将其分为几类,普通莫队,带修莫队,树上莫队(应该没别的了吧qwq我只会这三个)。

概述:莫队算法是用于解决什么问题呢?

给出莫队应用范围:对于一个序列在已知f[l,r]的情况下可以O1或者Ologn的复杂度求出f[l,r+1],f[l,r-1],f[l+1,r],f[l-1,r],并且题目不强制在线,那么我们就可以用莫队算法给出一个满意的复杂度。

那莫队的整体思想是什么呢?

其实是将题目中所给的询问记录下来,然后通过某种排序,使他们询问顺序发生改变,然后通过暴力移动左右两个边界(l,r)来处理处每一个询问的值,而如何排序,就需要用到一点分块的思想,来将其最坏情况复杂度变为n根号n。

一、普通莫队

这里先给出例题和代码,以及思路,后面将会给出详细的证明。

举个简单的例子,我现在有若干个物品,每一个物品对应一个颜色,给出若干个询问,请你给出对于每一个询问区间,它里面有多少种颜色。

[SDOI2009]HH的项链

这是一道可以用莫队解决的题目中最简单的一道了吧,他们好像都是用树状数组搞得,我也没往那想,单纯为了练莫队。

先贴上代码

技术分享
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,a[50005],m,pos[50005],f[50005],ans;
 4 struct Ques{
 5     int l,r,ans,id;
 6     bool operator < (const Ques &o)const{
 7         if(pos[l]!=pos[o.l])return pos[l]<pos[o.l];
 8         return r<o.r;
 9     }
10 }q[50005];
11 bool cmp(Ques x,Ques y){
12     return x.id<y.id;
13 }
14 int main()
15 {
16 //    freopen("1.txt","r",stdin);
17     scanf("%d",&n);
18     for(int i=1;i<=n;i++)scanf("%d",&a[i]);
19     scanf("%d",&m);
20     for(int i=1;i<=m;i++){
21         scanf("%d%d",&q[i].l,&q[i].r);
22         q[i].id=i;
23     }
24     int len=sqrt(n)+1;
25     for(int i=1;i<=n;i++)pos[i]=(i-1)/len+1;
26     sort(q+1,q+m+1);
27     int l=1,r=0;
28     for(int i=1;i<=m;i++){
29         while(r<q[i].r){
30             r++;
31             f[a[r]]++;
32             if(f[a[r]]==1)ans++;
33         }
34         while(r>q[i].r){
35             f[a[r]]--;
36             if(!f[a[r]])ans--;
37             r--;
38         }
39         while(l>q[i].l){
40             l--;
41             f[a[l]]++;
42             if(f[a[l]]==1)ans++;
43         }
44         while(l<q[i].l){
45             f[a[l]]--;
46             if(!f[a[l]])ans--;
47             l++;
48         }
49         q[i].ans=ans;
50     }
51     sort(q+1,q+m+1,cmp);
52     for(int i=1;i<=m;i++)printf("%d\n",q[i].ans);
53     return 0;
54 }
[SDOI2009]HH的项链

对于这道题,我们的思路是什么呢?先想一想最暴力的算法如何解决,对于每一次询问,我们从l枚举到r,并记录颜色数量,这样复杂度最坏情况下是n2的,显然不能令人满意,但如果我们可以将其将为n根号n,那么他就可以被完美的解决。

我们可以发现这道题是满足莫队的应用范围的,因为如果我知道l到r的颜色总数,那么我可以在o1的时间内求出[l,r+1]....等等,(放学啦...未完待续)

莫队小结

标签:sed   应该   多少   等等   logs   技术   应用   isp   强制   

原文地址:http://www.cnblogs.com/Turkeyghb/p/7643310.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!