题解 P4396 【[AHOI2013]作业】
莫队(块状暴力)。
首先这道题的数据略水,没有规定
然后这个长得就很像莫队(块状暴力),可以直接莫队(块状暴力)套上去,然后考虑怎么加点减点,显然可以用先用套路维护
(感觉可以奇偶性优化或者回滚莫队?有没有神仙加强一下数据啊)
#include<bits/stdc++.h>
#define MAXN 200005
#define reg register
#define inl inline
using namespace std;
struct Qry
{
int l,r,pos,x,y,id;
friend bool operator < (const Qry &x,const Qry &y)
{
return x.pos==y.pos?x.r<y.r:x.l<y.l;
}
}q[MAXN];
int n,m,a[MAXN],cnt[MAXN],ans1[MAXN],ans2[MAXN];
struct BIT
{
int c[MAXN];
inl int lowbit(reg int x)
{
return x&-x;
}
inl void Modify(reg int x,reg int val)
{
for(;x<=n;x+=lowbit(x)) c[x]+=val;
}
inl int Query(reg int x)
{
reg int res=0;
for(;x;x-=lowbit(x)) res+=c[x];
return res;
}
}A,B;
inl void Add(reg int x)
{
if(!cnt[x]) B.Modify(x,1);
A.Modify(x,1);
cnt[x]++;
}
inl void Del(reg int x)
{
A.Modify(x,-1);
cnt[x]--;
if(!cnt[x]) B.Modify(x,-1);
}
int main()
{
scanf("%d %d",&n,&m);
for(reg int i=1;i<=n;i++) scanf("%d",&a[i]);
reg int unt=sqrt(n);
for(reg int i=1;i<=m;i++)
{
scanf("%d %d %d %d",&q[i].l,&q[i].r,&q[i].x,&q[i].y);
q[i].id=i;
q[i].pos=(q[i].l-1)/unt+1;
}
sort(q+1,q+m+1);
reg int L=1,R=0;
for(reg int i=1;i<=m;i++)
{
while(L>q[i].l) Add(a[--L]);
while(R<q[i].r) Add(a[++R]);
while(L<q[i].l) Del(a[L++]);
while(R>q[i].r) Del(a[R--]);
ans1[q[i].id]=A.Query(q[i].y)-A.Query(q[i].x-1);
ans2[q[i].id]=B.Query(q[i].y)-B.Query(q[i].x-1);
}
for(reg int i=1;i<=m;i++) printf("%d %d\n",ans1[i],ans2[i]);
return 0;
}