BZOJ 1878 [SDOI2009]HH的项链 (莫队算法)

来源:互联网 发布:网站排名软件利搜 编辑:程序博客网 时间:2024/06/01 22:56

题意:

给你n个数字,然后查询某个区间有多少种数字

思路:

莫队裸题,用一个cnt维护区间数字的数量就能实现o(1)转移了

错误及反思:

代码:

#include<bits/stdc++.h>using namespace std;const int maxn= 50000+10;const int maxm= 1000000+10;int pos[maxn];int cnt[maxm];int arr[maxn];int n,m;int ans[200010];int now=0;struct query{    int l,r,id;}Q[200010];bool cmp(query a,query b){    if(pos[a.l]==pos[b.l])        return a.r<b.r;    return a.l<b.l;}inline void update(int num,int q){    if(cnt[num]!=0)        now--;    cnt[num]+=q;    if(cnt[num]!=0)        now++;}int main(){    scanf("%d",&n);    int block=sqrt(n);    for(int i=1;i<=n;i++)    {        scanf("%d",&arr[i]);        pos[i]=i/block;    }    scanf("%d",&m);    for(int i=0;i<m;i++)    {        scanf("%d%d",&Q[i].l,&Q[i].r);        Q[i].id=i;    }    sort(Q,Q+m,cmp);    for(int i=0,l=1,r=0;i<m;i++)    {        for(;l<Q[i].l;l++)            update(arr[l],-1);        for(;l>Q[i].l;l--)            update(arr[l-1],1);        for(;r<Q[i].r;r++)            update(arr[r+1],1);        for(;r>Q[i].r;r--)            update(arr[r],-1);        ans[Q[i].id]=now;    }    for(int i=0;i<m;i++)        printf("%d\n",ans[i]);}
原创粉丝点击