1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
| #include <bits/stdc++.h> #define MAXN 1000005 #define MAXM 1000005 using namespace std; inline int read(){ int x=0,f=1; char ch=getchar(); while (ch<'0'||ch>'9'){ if (ch=='-') f=-1; ch=getchar(); } while (ch>='0'&&ch<='9'){ x=(x<<3)+(x<<1)+(ch^'0'); ch=getchar(); } return x*f; } int a[MAXN],Size; static int pos[MAXN],cnt[MAXN],val1[MAXN]; static int val2[MAXN]; namespace Divide_Into_Blocks{ inline int Calc1(int l,int r){ int ans=0; for (register int i=l;i<=r;++i) ans+=cnt[i]>0; return ans; } inline int GetAns1(int a,int b){ int L=pos[a],R=pos[b]; if (L==R) return Calc1(a,b); int ans=0; for (register int i=L+1;i<=R-1;++i) ans+=val1[i]; return ans+Calc1(a,L*Size)+Calc1((R-1)*Size+1,b); } inline int Calc2(int l,int r){ int ans=0; for (register int i=l;i<=r;++i) ans+=cnt[i]; return ans; } inline int GetAns2(int a,int b){ int L=pos[a],R=pos[b]; if (L==R) return Calc2(a,b); int ans=0; for (register int i=L+1;i<=R-1;++i) ans+=val2[i]; return ans+Calc2(a,L*Size)+Calc2((R-1)*Size+1,b); } } using namespace Divide_Into_Blocks; struct Query{ int l,r,a,b,id; }q[MAXM]; inline bool operator < (const Query &a,const Query &b){ return pos[a.l]<pos[b.l]||(pos[a.l]==pos[b.l]&&((pos[a.l]&1)?a.r<b.r:a.r>b.r)); } int ans; inline void Add(int x){ ++val2[pos[x]]; if (++cnt[x]==1) ++val1[pos[x]]; } inline void Del(int x){ --val2[pos[x]]; if (--cnt[x]==0) --val1[pos[x]]; } int Ans1[MAXM],Ans2[MAXN]; int main(){ int n=read(),m=read(); Size=sqrt(n); for (register int i=1;i<=n;++i){ a[i]=read(); pos[i]=(i-1)/Size+1; } for (register int i=1;i<=m;++i){ q[i].l=read(),q[i].r=read(),q[i].a=read(),q[i].b=read(),q[i].id=i; } sort(q+1,q+1+m); int l=1,r=0; for (register int i=1;i<=m;++i){ while (l<q[i].l) Del(a[l++]); while (l>q[i].l) Add(a[--l]); while (r<q[i].r) Add(a[++r]); while (r>q[i].r) Del(a[r--]); Ans1[q[i].id]=GetAns1(q[i].a,q[i].b); Ans2[q[i].id]=GetAns2(q[i].a,q[i].b); } for (register int i=1;i<=m;++i){ printf("%d %d\n",Ans2[i],Ans1[i]); } }
|