P4396 [AHOI2013]作业
题目描述
详见:P4396 [AHOI2013]作业
solution
莫队+树状数组的裸题(莫队+分块,CDQ分治都可以,莫队+线段树大概需要卡常)。
时间复杂度
Code
#include<bits/stdc++.h>
using namespace std;
const int MAXN=2e5+50;inline int read()
{int f=1,x=0; char c=getchar();while (c<'0'||c>'9') { if (c=='-') f=-1; c=getchar(); }while (c>='0'&&c<='9') { x=(x<<3)+(x<<1)+(c^48); c=getchar(); }return x*f;
}int n,m,Size,Ans1[MAXN],Ans2[MAXN],a[MAXN],cnt[MAXN];
struct pnode{int l,r,a,b,id,x; } p[MAXN];
struct Tree_Array
{int tree[MAXN<<1];int lowbit(int x){ return x&(-x); }void change(int x,int y) { for (;x<=n;x+=lowbit(x)) tree[x]+=y; }int query(int x){ int ans=0; for (;x;x-=lowbit(x)) ans+=tree[x]; return ans; }
} tree1,tree2;
int compare(pnode x,pnode y){ return (x.x<y.x)||(x.x==y.x&&x.r<y.r); }
int main()
{n=read(),m=read(),Size=trunc(sqrt(n));for (int i=1;i<=n;i++) a[i]=read();for (int i=1;i<=m;i++){p[i].l=read(),p[i].r=read(),p[i].a=read(),p[i].b=read();p[i].id=i,p[i].x=(p[i].l-1)/Size+1;}sort(p+1,p+m+1,compare);int L=1,R=0;for (int i=1;i<=m;i++){while (L<p[i].l) cnt[a[L]]--,tree1.change(a[L],-1),tree2.change(a[L],cnt[a[L]]==0?-1:0),L++;while (L>p[i].l) L--,cnt[a[L]]++,tree1.change(a[L], 1),tree2.change(a[L],cnt[a[L]]==1? 1:0);while (R<p[i].r) R++,cnt[a[R]]++,tree1.change(a[R], 1),tree2.change(a[R],cnt[a[R]]==1? 1:0);while (R>p[i].r) cnt[a[R]]--,tree1.change(a[R],-1),tree2.change(a[R],cnt[a[R]]==0?-1:0),R--;Ans1[p[i].id]=tree1.query(p[i].b)-tree1.query(p[i].a-1);Ans2[p[i].id]=tree2.query(p[i].b)-tree2.query(p[i].a-1);}for (int i=1;i<=m;i++) printf("%d %d\n",Ans1[i],Ans2[i]);return 0;
}