Description
Autumn和Bakser又在研究Gty的妹子序列了!但他们遇到了一个难题。
对于一段妹子们,他们想让你帮忙求出这之内美丽度∈[a,b]的妹子的美丽度的种类数。
为了方便,我们规定妹子们的美丽度全都在[1,n]中。
给定一个长度为n(1<=n<=100000)的正整数序列s(1<=si<=n),对于m(1<=m<=1000000)次询问“l,r,a,b”,每次输出sl…sr中,权值∈[a,b]的权值的种类数。
【题目分析】
分块。
【代码】
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int n,m,T,L[5001],R[5001],cnt;
int v[100001];
struct line{int l,r,a,b,num;}q[1000001];
inline bool cmp1(line a,line b){return a.l<b.l;}
inline bool cmp2(line a,line b){return a.r<b.r;}
int b[100001],bel[100001],lab[501],st[501],ed[501],top=0,T2;
int out[1000001];
int main()
{
scanf("%d%d",&n,&m);
for (int i=1;i<=n;++i) scanf("%d",&v[i]);
for (int i=1;i<=m;++i)
{
scanf("%d%d%d%d",&q[i].l,&q[i].r,&q[i].a,&q[i].b);
q[i].num=i;
}
sort(q+1,q+m+1,cmp1);
T=sqrt(m);
for(int i=1;i<=m;i+=T)
{
++cnt;
L[cnt]=i;
R[cnt]=i+T-1;
}
R[cnt]=m;
for (int i=1;i<=cnt;++i) sort(q+L[i],q+R[i]+1,cmp2);
T2=sqrt(n);
for (int i=1;i<=n;i+=T2)
{
++top;
st[top]=i;
ed[top]=i+T2-1;
}
ed[top]=n;
for (int i=1;i<=top;++i)
for (int j=st[i];j<=ed[i];++j)
bel[j]=i;
int l=1,r=0;
for (int i=1;i<=m;++i)
{
// printf("for question %d %d %d %d\n",q[i].l,q[i].r,q[i].a,q[i].b);
while (r<q[i].r)
{
r++;
b[v[r]]++; //printf("%d ++\n",v[r]);
if (b[v[r]]==1) lab[bel[v[r]]]++;
}
while (l>q[i].l)
{
l--;
b[v[l]]++; //printf("%d ++\n",v[l]);
if (b[v[l]]==1) lab[bel[v[l]]]++;
}
while (r>q[i].r)
{
b[v[r]]--; //printf("%d --\n",v[r]);
if (b[v[r]]==0) lab[bel[v[r]]]--;
r--;
}
while (l<q[i].l)
{
b[v[l]]--; //printf("%d --\n",v[l]);
if (b[v[l]]==0) lab[bel[v[l]]]--;
l++;
}
int ll=bel[q[i].a],rr=bel[q[i].b],ans=0;
// printf("value %d %d at %d %d\n",q[i].a,q[i].b,ll,rr);
if (ll+1==rr||ll==rr)
{
// printf("baoli\n");
for (int j=q[i].a;j<=q[i].b;++j)
{
// printf("%d\n",j);
if (b[j]) ans++;
}
// printf("Ans is %d\n",ans);
}
else
{
for (int j=q[i].a;j<=ed[ll];++j) if (b[j]) ans++;
for (int j=st[rr];j<=q[i].b;++j) if (b[j]) ans++;
// printf("outof lab is %d\n",ans);
for (int j=ll+1;j<rr;++j) ans+=lab[j];
}
// printf("ans is %d\n",ans);
out[q[i].num]=ans;
}
for (int i=1;i<=m;++i) printf("%d\n",out[i]);
}