莫队+值域分块O2 88分卡常不过求调弄
查看原帖
莫队+值域分块O2 88分卡常不过求调弄
707513
LBYYSM_123楼主2023/9/16 21:04
#include<bits/stdc++.h>
using namespace std;
int n,m,q,ksize;
int blk[100001];
int st[321],ed[321];
int a[100001];
namespace IN {
    const int MAX_IN = 1000000;
    #define getc() (p1 == p2 && (p2 = (p1 = buf) + inbuf -> sgetn(buf, MAX_INPUT), p1 == p2) ? EOF : *p1++)
    char buf[MAX_IN], *p1, *p2;
    template <typename T> inline bool redi(T &x) {
        static streambuf *inbuf = cin.rdbuf();
        x = 0;
        register int f = 0, flag = false;
        register char ch = getc();
        while (!isdigit(ch)) {
            if (ch == '-') f = 1;
        ch = getc();
        }
        if (isdigit(ch)) x = x * 10 + ch - '0', ch = getc(),flag = true;
        while (isdigit(ch)) {
            x = x * 10 + ch - 48;
            ch = getc();
        }
        x = f ? -x : x ;
        return flag;
    }
    template <typename T,typename ...Args> inline bool redi(T& a,Args& ...args) {
       return redi(a) && redi(args...);
    }
    #undef getc
}
struct{
	int xian;
	int hou;
	void write(){
		printf("%d %d\n",xian,hou);
	}
}ans[100001];
int cnt[100001][2];
int bel[100001];
int kuaisum[321][2];
struct kuai{
	int l;
	int r;
	int a;
	int b;
	int id;
	bool operator <(const kuai& a)const{
		if(blk[l]==blk[a.l])
			if(blk[l]&1) return r<a.r;
			else return r>a.r;
		else
			return l<a.l;
	}
}ask[100001]; 
inline void add(int wei){
	cnt[a[wei]][0]++,kuaisum[bel[a[wei]]][0]++;
	if(cnt[a[wei]][0]==1)
		cnt[a[wei]][1]++,kuaisum[bel[a[wei]]][1]++;
}
inline void sub(int wei){
	cnt[a[wei]][0]--,kuaisum[bel[a[wei]]][0]--;
	if(cnt[a[wei]][0]==0)
		cnt[a[wei]][1]--,kuaisum[bel[a[wei]]][1]--;
}
void query(int id,int La,int Lb){
	register int ans1=0,ans2=0;
	if(bel[La]==bel[Lb]){
		for(register int i=La;i<=Lb;i++)
			ans1+=cnt[i][0],ans2+=cnt[i][1];
	}
	else{
		for(register int i=bel[La]+1;i<bel[Lb];i++)
			ans1+=kuaisum[i][0],ans2+=kuaisum[i][1];
		for(register int i=La;i<=ed[bel[La]];i++)
			ans1+=cnt[i][0],ans2+=cnt[i][1];
		for(register int i=st[bel[Lb]];i<=Lb;i++)
			ans1+=cnt[i][0],ans2+=cnt[i][1];
	}
	ans[id].xian=ans1,ans[id].hou=ans2;
}
signed main(){
	IN::redi(n,m);q=sqrt(n);ksize=317;
	for(register int i=1;i<=ksize;i++)
		st[i]=100000/ksize*(i-1)+1,ed[i]=100000/ksize*i;ed[ksize]=100000;
	for(register int i=1;i<=ksize;i++)
		for(register int j=st[i];j<=ed[i];j++)
			bel[j]=i;
	for(register int i=1;i<=n;i++)
		IN::redi(a[i]),blk[i]=n/q+1;
	for(register int i=1;i<=m;i++){
		IN::redi(ask[i].l,ask[i].r,ask[i].a,ask[i].b);
		ask[i].id=i;
	}
	sort(ask+1,ask+1+m);
	register int l=1,r=0;
	for(register int i=1;i<=m;i++){
		register int linl=ask[i].l,linr=ask[i].r;
		while(l>linl) add(--l);
		while(r<linr) add(++r);
		while(l<linl) sub(l++);
		while(r>linr) sub(r--);
		query(ask[i].id,ask[i].a,ask[i].b);
	}
	for(register int i=1;i<=m;i++)
		ans[i].write();
	return 0;
} 
2023/9/16 21:04
加载中...