也不说了直接上板子
莫队模板
#include<bits/stdc++.h>
using namespace std;
struct ques{
int id,l,r;
}q[200010];//结构体存每个询问,注意要记录询问顺序以便输出
const int block=1300;//分的块大小
int a[30010],ans[200010],res=0;//a数组数据,ans存各个询问答案,res当前左右端点答案
void add(int pos)//加入新点
{
//视情况,略..
}
void del(int pos)//删除点
{
//视情况,略..
}
bool cmp(ques a,ques b)//排序比较函数
{return a.l/block==b.l/block?a.r<b.r:a.l/block<b.l/block;}
int main()
{
int n,m,nowl,nowr;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
scanf("%d",&m);
for(int i=1;i<=m;i++)
scanf("%d%d",&q[i].l,&q[i].r),q[i].id=i; //读入数据及询问
nowl=0;nowr=0;//当前左右端点
sort(q+1,q+m+1,cmp);//给询问排序
for(int i=1;i<=m;i++)
{
while(nowr<q[i].r)//当前小于询问右端点,往右拓展
{
add(nowr+1);
nowr++;
}
while(nowl>q[i].l)//往左,类似
{
add(nowl-1);
nowl--;
}
while(nowr>q[i].r)//当前大于询问右端点,往左删除
{
del(nowr);
nowr--;
}
while(nowl<q[i].l)//往右,类似
{
del(nowl);
nowl++;
}
ans[q[i].id]=res;//存下该次询问答案
}
//输出,略
}//这里需要注意的是4个while循环一般先搞添加再搞删除,以免l到r右边产生奇怪错误
模板题–SPOJ DQUERY
题意:给一个串,里面一堆整数,再给出一堆询问,问给定区间不相同数的个数.
数据范围(串中数数量<=30000,每个数大小<=1000000,询问数<=200000)
裸题,莫队板子贴上去就行,复杂度询问数*根号(数的数量)
#include<bits/stdc++.h>
using namespace std;
struct ques{
int id,l,r;
}q[200010];
const int block=1300;int a[30010],belong[30010],ans[200010],res=0;int vis[1000010]={0};
void add(int pos)
{
vis[a[pos]]++;
if(vis[a[pos]]==1)res++;
}
void del(int pos)
{
vis[a[pos]]--;
if(vis[a[pos]]==0)res--;
}
bool cmp(ques a,ques b)
{return a.l/block==b.l/block?a.r<b.r:a.l/block<b.l/block;}
int main()
{
int n,m,nowl,nowr;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
scanf("%d",&m);
for(int i=1;i<=m;i++)
scanf("%d%d",&q[i].l,&q[i].r),q[i].id=i;
sort(q+1,q+m+1,cmp);
nowl=0;nowr=0;
for(int i=1;i<=m;i++)
{
while(nowr<q[i].r)
{
add(nowr+1);
nowr++;
}
while(nowl>q[i].l)
{
add(nowl-1);
nowl--;
}
while(nowr>q[i].r)
{
del(nowr);
nowr--;
}
while(nowl<q[i].l)
{
del(nowl);
nowl++;
}
ans[q[i].id]=res;
}
for(int i=1;i<=m;i++)
printf("%d\n",ans[i]);
}