【BZOJ1878】【codevs2307】HH的项链,莫队算法

来源:互联网 发布:生物信息学 知乎 编辑:程序博客网 时间:2024/06/05 04:37

传送门1
传送门2
写在前面:信息课上的莫队练习
思路:比小Z的袜子还要简单些,不过BZOJ上4s的总时限确实把我吓了一跳
注意:种类编号为0-1000000,小心数组越界导致RE
代码:

#include"bits/stdc++.h"using namespace std;int m,n,tot,last_l=1,last_r;int a[50010],block[50010],flag[1000001];struct os{    int l,r,num,ans;}q[200010];int cmp1(os x,os y){    if (block[x.l]<block[y.l]) return 1;    if (block[x.l]>block[y.l]) return 0;    return x.r<y.r;}int cmp2(os x,os y){return x.num<y.num;}int in(){    int f=1,t=0;    char ch=getchar();    while (ch>'9'||ch<'0')    {        if (ch=='-') f=-1;        ch=getchar();    }    while (ch>='0'&&ch<='9') t=t*10+ch-'0',ch=getchar();    return f*t;}main(){    n=in();    for (int i=1;i<=n;i++) a[i]=in();    block[0]=sqrt(n);    for (int i=1;i<=n;i++)    block[i]=(i-1)/block[0]+1;    m=in();    for (int i=1;i<=m;i++)    q[i].l=in(),    q[i].r=in(),    q[i].num=i;    sort(q+1,q+m+1,cmp1);    for (int i=1;i<=m;i++)    {        if (q[i].r>last_r)        for (int j=last_r+1;j<=q[i].r;j++)        {            if (!flag[a[j]]) tot++;            flag[a[j]]++;        }        if (q[i].r<last_r)        for (int j=last_r;j>q[i].r;j--)        {            flag[a[j]]--;            if (!flag[a[j]]) tot--;        }        if (q[i].l<last_l)        for (int j=last_l-1;j>=q[i].l;j--)        {            if (!flag[a[j]]) tot++;            flag[a[j]]++;        }        if (q[i].l>last_l)        for (int j=last_l;j<q[i].l;j++)        {            flag[a[j]]--;            if (!flag[a[j]]) tot--;        }        last_l=q[i].l;        last_r=q[i].r;        q[i].ans=tot;    }    sort(q+1,q+m+1,cmp2);    for (int i=1;i<=m;i++) printf("%d\n",q[i].ans);}
0 0
原创粉丝点击