标签:int div bool 相同 for 排序 高效 复杂 随机
昨天的模拟赛T3是个非常恶心的东东,不过今天获知有人莫队+O3卡常A了==
但是原来OD表示莫队目前没什么用不用学,就没学过,所以昨天无奈不会打
但是今天哼哼,学会了这个新的知识点,而且觉得还是挺好用的啊
毕竟暴力是哪里都能用得上的。。。
所谓莫队,是一个优雅的暴力
解决的问题就是离线区间询问,好像是无敌的。(然而区间修改我目前还不会,而且区间最值好像也不会,而且区间最值也不用莫队233)
首先我们知道区间[L,R],那么我们一定能暴力求出来[L‘,R‘]。我们将所有询问存起来,暴力求出来第一个区间,然后用这个区间去更新下一个区间(其实就是相当于不用算两区间重合的部分了)
为了我们暴力求的不重合的区间尽量少,我们会选择排序。那么如何排序呢?肯定不能严格按第一关键左端点升序,第二关键右端点升序来搞。对于随机数据这样还好,但是对于出题人存心卡你的数据效率就又降下来了。比如区间[1,100]推区间[2,3],肯定会很慢。
所以为了解决这个问题,我们需要让左端点“大概”呈上升趋势,然后搞右端点(就是让两个区间之间离得近)。于是出现了最小曼哈顿距离生成树(然而我们并不用它233)
有一个优美的方法那就是另一个暴力——分块大法!
当然我们这里只需要分块中的块就好啦,我们把所有询问区间以左端点的块升序排序,如果相同就以右端点(它本身)排序,这样就能提高效率
时间复杂度大概是O(n*√n) (拒绝证明因为不会)
然后我们只需要循环一遍,用上一个区间求这个区间(暴力更新不重合部分即可),然后储存答案最后输出即可。
上例题:[SDOI2009]HH的项链 比较裸的莫队了
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define pos(i,a,b) for(int i=(a);i<=(b);i++)
#define N 210000
#define LL long long
int a[N];
int n,m,k;
int match[N],len,cnt[1001000];
LL ans[N];
struct haha{
int l,r,id;
}edge[N];
bool cmp(const haha &a,const haha &b){
if(match[a.l]==match[b.l]) return a.r<b.r;
return match[a.l]<match[b.l];
}
void add(int i,int num){
if(cnt[num]==0) ans[i]++;
cnt[num]++;
}
void erase(int i,int num){
cnt[num]--;
if(cnt[num]==0) ans[i]--;
}
int main(){
scanf("%d",&n);
len=(int)sqrt(n+0.5);
//cout<<len<<endl;
pos(i,1,n) scanf("%d",&a[i]),k=max(a[i],k);
pos(i,1,n){
match[i]=(i-1)/(len+1);
}
scanf("%d",&m);
pos(i,1,m){
scanf("%d%d",&edge[i].l,&edge[i].r);
edge[i].id=i;
}
sort(edge+1,edge+m+1,cmp);
int lastl,lastr;
lastl=edge[1].l;lastr=edge[1].r;
pos(i,lastl,lastr){
cnt[a[i]]++;
}
pos(i,0,k){
if(cnt[i]!=0) ans[edge[1].id]++;
}
pos(i,2,m){
ans[edge[i].id]=ans[edge[i-1].id];
int nowl=edge[i].l,nowr=edge[i].r;
if(nowl>=lastl) pos(j,lastl,nowl-1) erase(edge[i].id,a[j]);
else pos(j,nowl,lastl-1) add(edge[i].id,a[j]);
if(nowr>=lastr) pos(j,lastr+1,nowr) add(edge[i].id,a[j]);
else pos(j,nowr+1,lastr) erase(edge[i].id,a[j]);
lastr=nowr;lastl=nowl;
}
pos(i,1,m) printf("%lld\n",ans[i]);
return 0;
}
好啦新技能 莫队 get√
标签:int div bool 相同 for 排序 高效 复杂 随机
原文地址:http://www.cnblogs.com/Hallmeow/p/7581798.html