莫队求助卡常
查看原帖
莫队求助卡常
255095
PragmaGCC楼主2021/2/19 14:04

rt,剩 3 个点过不去,块长调不动了

#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
namespace qio {
	#define isdigit(ch) (ch >= '0' && ch <= '9')
	#define debug(...) fprintf(stderr,__VA_ARGS__)
	#define Debug(x) debug("Passing [%s] in LINE %d , %s=%d\n",__FUNCTION__,__LINE__,#x,x)
	char buf[1<<23],*p1=buf,*p2=buf;
	#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
	inline int read() {
		int x=0,f=1;char ch=getchar();
		while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
		while(isdigit(ch)) x=x*10+(ch^48),ch=getchar();
		return x*f;
	}
}
using namespace qio;
const int N = 1e6 + 5;
int n, m, a[N], block;
int pos[N], cnt[N], ans;
struct Query {
	int l, r, id;
} q[N];
int Ans[N];
inline bool cmp(Query a, Query b) {
	if (pos[a.l] == pos[b.l]) return (pos[a.l] & 1) ? (a.r < b.r) : (a.r > b.r);
	return pos[a.l] < pos[b.l];
}
inline void add(int p) {
	cnt[a[p]]++;
	if (cnt[a[p]] == 1) ans++;
}
inline void del(int p) {
	cnt[a[p]]--;
	if (cnt[a[p]] == 0) ans--;
}
int main(void) {
	n = read();
	block = 1700;
	for (register int i=1; i<=n; i++) a[i] = read(), pos[i] = (i-1) / block + 1;
	m = read();
	for (register int i=1; i<=m; i++) q[i].l = read(), q[i].r = read(), q[i].id = i;
	sort(q + 1, q + 1 + m, cmp);
	register int l=1, r=0;
	for (register int i=1; i<=m; i++) {
		while(r < q[i].r) add(++r);
		while(r > q[i].r) del(r--);
		while(l > q[i].l) add(--l);
		while(l < q[i].l) del(l++);
		Ans[q[i].id] = ans;
	}
	for (register int i=1; i<=m; i++) printf("%d\n", Ans[i]);
	return 0;
}
2021/2/19 14:04
加载中...