# BZOJ 3809: Gty的二逼妹子序列 & 3236: [Ahoi2013]作业 [莫队]

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define pii pair<int, int>
#define MP make_pair
#define fir first
#define sec second
typedef long long ll;
const int N=1e5+5, M=1e6+5, BN=320, BS=320;
inline int read(){
char c=getchar();int x=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
return x*f;
}

int n, Q, a[N], l, r, x, y;
struct _blo{int l, r;} b[BN];
int block, m, pos[N];
struct Block{
inline void ini(){
block=sqrt( n );
m=(n-1)/block+1;
for(int i=1; i<=n; i++) pos[i]=(i-1)/block+1;
for(int i=1; i<=m; i++) b[i].l=(i-1)*block+1, b[i].r=i*block; b[m].r=n;
}
int kind[BS], c[N], sum[BS];
inline void add(int v) {
c[v]++; sum[pos[v]]++;
if(c[v]==1) kind[pos[v]]++;
}
inline void del(int v) {
c[v]--; sum[pos[v]]--;
if(c[v]==0) kind[pos[v]]--;
}
pii que(int l,int r) {
int pl=pos[l], pr=pos[r], ans1=0, ans2=0;
if(pl==pr) for(int i=l; i<=r; i++) ans1+=c[i], ans2+= c[i]>0;
else{
for(int i=pl+1; i<pr; i++) ans1+=sum[i], ans2+= kind[i];
for(int i=l; i<=b[pl].r; i++) ans1+=c[i], ans2+= c[i]>0;
for(int i=b[pr].l; i<=r; i++) ans1+=c[i], ans2+= c[i]>0;
}
return MP(ans1, ans2);
}
}B;

struct meow{
int l, r, x, y, qid;
bool operator <(const meow &a) const{return pos[l]==pos[a.l] ? r<a.r : pos[l]<pos[a.l];}
}q[M];
pii ans[M];
void modui(){
int l=1, r=0;
for(int i=1; i<=Q; i++){
while(r<q[i].r) r++, B.add(a[r]);
while(r>q[i].r) B.del(a[r]), r--;
while(l<q[i].l) B.del(a[l]), l++;
while(l>q[i].l) l--, B.add(a[l]);
ans[q[i].qid]= B.que(q[i].x, q[i].y);
}
}

int main() {
freopen("in","r",stdin);
n=read(); Q=read();
for(int i=1; i<=n; i++) a[i]=read();
for(int i=1; i<=Q; i++) l=read(), r=read(), x=read(), y=read(), q[i]=(meow){l, r, x, y, i};
B.ini();
sort(q+1, q+1+Q);
modui();
for(int i=1; i<=Q; i++) printf("%d %d\n",ans[i].fir, ans[i].sec);
}

Copyright：http://www.cnblogs.com/candy99/
posted @ 2017-03-20 08:27  Candy?  阅读(198)  评论(0编辑  收藏  举报