题目链接:
http://www.lydsy.com/JudgeOnline/problem.php?id=3809
题解:
bzoj脸太黑,蜜汁超时,具体算法是莫队+分块,唉
代码:(超时的代码)
#include<iostream>
#include<algorithm>
#include<string.h>
#include<stdio.h>
#include<math.h>
#define maxn (100005)
#define maxm (1000005)
using namespace std;
int len;
struct node{
int l,r;
int a,b;
int id;
}q[maxm];
int cmp(node x,node y)
{
int idx=x.l/len;
int idy=y.l/len;
if (idx!=idy)
return idx<idy;
else return x.r<y.r;
}
int n,m,s[maxn],ans[maxm],sq[maxn],cnt[maxn],k[maxn];
int f(int x,int y)
{
int ans=0;
int X=sq[x];
int Y=sq[y];
if (sq[x]==sq[y])
{
for (int i=x;i<=y;i++)
if (cnt[i]>0) ans++;
return ans;
}
while(X==sq[x])
{
if (cnt[x]>0) ans++;
x++;
}
while(Y==sq[y])
{
if (cnt[y]>0) ans++;
y--;
}
for (int i=sq[x];i<=sq[y];i++) ans+=k[i];
return ans;
}
int main()
{
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++)
scanf("%d",&s[i]);
len=sqrt(n);
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].id=i;
}
for (int i=1;i<=n;i++)
sq[i]=(i-1)/len+1;
sort(q+1,q+1+m,cmp);
int nowL=0,nowR=0;
for (int i=1;i<=m;i++)
{
node now=q[i];
while (now.l > nowL)
{
cnt[s[nowL]]--;
if (cnt[s[nowL]]==0) k[sq[s[nowL]]]--;
nowL++;
}
while(now.l < nowL)
{
nowL--;
cnt[s[nowL]]++;
if (cnt[s[nowL]]==1) k[sq[s[nowL]]]++;
}
while(now.r < nowR)
{
cnt[s[nowR]]--;
if (cnt[s[nowR]]==0) k[sq[s[nowR]]]--;
nowR--;
}
while(now.r > nowR)
{
nowR++;
cnt[s[nowR]]++;
if (cnt[s[nowR]]==1) k[sq[s[nowR]]]++;
}
ans[now.id]=f(now.a,now.b);
}
for (int i=1;i<=m;i++)
printf("%d\n",ans[i]);
}