莫队+树状数组+读入优化 75s+AC(PS:我居然先写的线段树)code:
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#define mid (l+r)/2
#define lch i<<1,l,mid
#define rch i<<1|1,mid+1,r
using namespace std;
char * p=(char *)malloc(50000000);
inline int in(){
int x=0;
while(*p<'0'||*p>'9')++p;
while(*p>='0'&&*p<='9')x=x*10+*p++-'0';
return x;
}
struct hp{
int l,r,a,b,st,num;
}qst[1000001];
int ans[1000001][2];
int node[400001][2];
int vis[1000001];
int n,m,a[100001],L,R,size;
int cmp(const hp &a,const hp &b)
{
if ((a.st<b.st)||(a.st==b.st&&a.r<b.r))
return 1;
else return 0;
}
int lowbit(int x){return x&(-x); }
inline void bit_ins0(int x,int a)
{
while (x<=n)
{node[x][0]+=a; x+=lowbit(x);}
}
inline void bit_ins1(int x,int a)
{
while (x<=n)
{node[x][1]+=a; x+=lowbit(x);}
}
inline int query0(int x)
{
int ans=0;
while (x)
{
ans+=node[x][0];
x-=lowbit(x);
}
return ans;
}
inline int query1(int x)
{
int ans=0;
while (x)
{
ans+=node[x][1];
x-=lowbit(x);
}
return ans;
}
inline void work(int i)
{
int l=qst[i].l,r=qst[i].r;
while (L<l)
{
bit_ins0(a[L],-1);
if (vis[a[L]]==1) bit_ins1(a[L],-1);
vis[a[L]]--;
L++;
}
while (L>l)
{
L--;
bit_ins0(a[L],1);
if (vis[a[L]]==0) bit_ins1(a[L],1);
vis[a[L]]++;
}
while (R<r)
{
R++;
bit_ins0(a[R],1);
if (vis[a[R]]==0) bit_ins1(a[R],1);
vis[a[R]]++;
}
while (R>r)
{
bit_ins0(a[R],-1);
if (vis[a[R]]==1) bit_ins1(a[R],-1);
vis[a[R]]--;
R--;
}
ans[qst[i].num][0]=query0(qst[i].b)-query0(qst[i].a-1);
ans[qst[i].num][1]=query1(qst[i].b)-query1(qst[i].a-1);
}
int main()
{
int i,per;
fread(p,1,50000000,stdin);
n=in(),m=in();
for (i=1;i<=n;++i)a[i]=in();
per=sqrt(n); size=n;
for (i=1;i<=m;++i)
{
qst[i].l=in(),qst[i].r=in(),qst[i].a=in(),qst[i].b=in();
qst[i].st=(qst[i].l/per)+1;
qst[i].num=i;
}
sort(qst+1,qst+m+1,cmp);
for (i=qst[1].l;i<=qst[1].r;++i)
{
bit_ins0(a[i],1);
if (vis[a[i]]==0) bit_ins1(a[i],1);
vis[a[i]]++;
}
ans[qst[1].num][0]=query0(qst[1].b)-query0(qst[1].a-1);
ans[qst[1].num][1]=query1(qst[1].b)-query1(qst[1].a-1);
L=qst[1].l; R=qst[1].r;
for (i=2;i<=m;++i)
work(i);
for (i=1;i<=m;++i)
printf("%d %d\n",ans[i][0],ans[i][1]);
}