莫队+分块的有机结合

· · 题解

莫队+分块

好像很多写莫队+分块的,但是代码可读性个人感觉有点差,就写了个码风奇特的版本给各位带哥康康。

第一次写题解,审核大大给个过8 !ლ(°◕‵ƹ′◕ლ) 话说这题好水

对于本题,在察觉了出现数字个数时就很容易察觉到(杀意感知)可以用莫队处理(离线),但是对于区间内符合条件的x的总个数呢?想到可以用莫队和分块有机结合处理,就可以A掉本题了!

看代码,GKD

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+7;
int n,m,q[N],a[N],l=1,r,blo;
int appnum[N],appq[N],tot[N];

struct node
{
    int l,r,a,b,id;
}ask[N];//存储输入 

struct node1
{
    int a1,a2;
}ans[N];//储存答案,有两个输出,一个是种类数,一个是个数

bool cmp(node x,node y)
{
    if(q[x.l]!=q[y.l])
    return q[x.l]<q[y.l];
    else return x.r<y.r;
}

void add(int x)
{
    appnum[x]++;
    appq[q[x]]++;
    if(appnum[x]==1) tot[q[x]]++;
}

void del(int x)
{
    appnum[x]--;
    appq[q[x]]--;
    if(appnum[x]==0) tot[q[x]]--;
}

void getans(int a,int b,int k)//分块找答案 
{
    for(int i=a;i<=min(b,q[a]*blo);i++)
        if(appnum[i]) ans[k].a1+=appnum[i],ans[k].a2++;

    if(q[a]!=q[b])
        for(int i=(q[b]-1)*blo+1;i<=b;i++)
            if(appnum[i]) ans[k].a1+=appnum[i],ans[k].a2++;

    for(int i=q[a]+1;i<=q[b]-1;i++)
    { 
        ans[k].a1+=appq[i];
        ans[k].a2+=tot[i];
    }
}

inline int read()
{
   int s=0,w=1;
   char ch=getchar();
   while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
   while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
   return s*w;
}

int main()
{
    //freopen("homework.in","r",stdin);
    //freopen("homework.out","w",stdout);

    n=read();m=read();
    blo=sqrt(n);

    for(int i=1;i<=n;i++)
    {
        a[i]=read();
        q[i]=(i-1)/blo+1;//分块
    }

    for(int i=1;i<=m;i++)
    {
        ask[i].l=read();ask[i].r=read();ask[i].a=read();ask[i].b=read();
        ask[i].id=i;//输入数据
    }

    sort(ask+1,ask+m+1,cmp);//对查询区间的排序节约时间,莫队基操

    for(int i=1;i<=m;i++)
    {   //莫队先统计 
        while(r<ask[i].r)   add(a[++r]);
        while(r>ask[i].r)   del(a[r--]);
        while(l>ask[i].l)   add(a[--l]);
        while(l<ask[i].l)   del(a[l++]);

        getans(ask[i].a,ask[i].b,ask[i].id);
    }

    for(int i=1;i<=m;i++)
        printf("%d %d\n",ans[i].a1,ans[i].a2);

    return 0;
}