所以这题真的不能用莫队卡过去了吗
查看原帖
所以这题真的不能用莫队卡过去了吗
310801
Spouter_27楼主2021/8/28 09:48

如果可以麻烦大佬发一下代码

如果不行,那洛谷还有什么数据比较小的静态莫队的模板啊

这里放上惨遭爆炸的莫队代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6;
typedef long long ll;
inline void read(ll &x);
inline void write(ll x);
int n,t[N+10],m,a[N+10],f[N+10],sum=1,lz=1,rz=1;
struct ask{
	int l,r,answer,num;
	ask(){
		l=r=num=answer=0;
	}
}q[N+10];
bool cmp1(const ask &a,const ask &b){
	return f[a.l]==f[b.l]?(f[a.l]&1)?a.r<b.r:a.r>b.r:f[a.l]<f[b.l];
}
bool cmp2(const ask &a,const ask &b){
	return a.num<b.num;
}
signed main(){
	read(n);
	for(int i=1;i<=n;i++){
		read(a[i]);
	}
	t[a[1]]++;
	
	read(m);
	double sqrtn=1.0*n/sqrt(m*2.0/3);
	for(int i=1;i<=n;i++){
		f[i]=(int)(i/sqrtn);
	}
	for(int i=1;i<=m;i++){
		read(q[i].l);
		read(q[i].r);
		q[i].num=i;
	}
	sort(q+1,q+m+1,cmp1);
	/*for(int i=1;i<=m;i++){
		cout<<q[i].l<<" "<<q[i].r<<" "<<f[q[i].l]<<" "<<q[i].num<<endl;
	}*/
	for(int i=1;i<=m;i++){
		for(int j=rz+1;j<=q[i].r;j++){
			t[a[j]]++;
			if(t[a[j]]==1)	sum++;
		}
		for(int j=rz;j>q[i].r;j--){
			t[a[j]]--;
			if(t[a[j]]==0)	sum--;
		}
		for(int j=lz;j<q[i].l;j++){
			t[a[j]]--;
			if(t[a[j]]==0)	sum--;
		}
		for(int j=lz-1;j>=q[i].l;j--){
			t[a[j]]++;
			if(t[a[j]]==1)	sum++;
		}
		lz=q[i].l,rz=q[i].r;
		q[i].answer=sum;
	} 
	sort(q+1,q+m+1,cmp2);
	for(int i=1;i<=m;i++){
		write(q[i].answer);
		putchar('\n');
	}
}
inline void read(ll &x){
	x=0;
	register int f=1;
	register 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-'0';
		c=getchar();
	}
	x*=f;
}
void write(ll x){
	if(x<0){
		putchar('-');
		x=~x+1;
	}
	if(x>=10) write(x/10);
	putchar(x%10+'0');
}
2021/8/28 09:48
加载中...