莫隊模板+模板題
阿新 • • 發佈:2019-02-09
也不說了直接上板子
莫隊模板
#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]);
}