Codeforces1000F One Occurrence

主席树题我要写莫队!!

Description

link

求区间内的出现一次的数字,有多个给任一

(n,T le 5 imes10^5)

Solution

然后去学习了一个奇偶优化

就是 (cmp) 函数这么写:

	inline bool cmp(node x,node y)
	{
		return b[x.l]==b[y.l]?(b[x.l]&1)?x.r<y.r:x.r>y.r:x.l<y.l;
	}

剩下的和普通的莫队差不多,注意在加减出现次数的时候搞个栈,把所有的出现次数为 (1) 的数字存下来

然后就可以了

关于奇偶优化,代码很好背对吧……

画画图模拟一下大概就能理解这个过程

Code

#include<bits/stdc++.h>
using namespace std;
namespace yspm{
	inline int read()
	{
		int res=0,f=1; char k;
		while(!isdigit(k=getchar())) if(k=='-') f=-1;
		while(isdigit(k)) res=res*10+k-'0',k=getchar();
		return res*f;
	}
	const int N=5e5+10;
	int st[N],top,app[N],id[N],n,a[N],T,b[N],l=1,r=0,bl,ans[N];
	inline void add(int x)
	{
		app[x]++;
		if(app[x]==1) st[++top]=x,id[x]=top;
		if(app[x]==2) st[id[x]]=st[top],id[st[top]]=id[x],st[top]=id[x]=0,top--;
		return ;
	}
	inline void del(int x)
	{
		app[x]--;
		if(app[x]==1) st[++top]=x,id[x]=top;
		if(app[x]==0) st[id[x]]=st[top],id[st[top]]=id[x],st[top]=id[x]=0,top--;
		return ;
	}
	struct node{
		int id,l,r;
	}q[N];
	inline bool cmp(node x,node y)
	{
		return b[x.l]==b[y.l]?(b[x.l]&1)?x.r<y.r:x.r>y.r:x.l<y.l;
	}
	signed main()
	{
		n=read(); bl=sqrt(n); for(int i=1;i<=n;++i) a[i]=read(),b[i]=i/bl+1;
		T=read(); for(int i=1;i<=T;++i) q[i].l=read(),q[i].r=read(),q[i].id=i;
		sort(q+1,q+T+1,cmp);
		for(int i=1;i<=T;++i)
		{
			while(l<q[i].l) del(a[l++]);
			while(l>q[i].l) add(a[--l]);
			while(r>q[i].r) del(a[r--]);
			while(r<q[i].r) add(a[++r]);
			ans[q[i].id]=st[top];
		} for(int i=1;i<=T;++i) printf("%d
",ans[i]);
		return 0;
	}
}
signed main(){return yspm::main();}
原文地址:https://www.cnblogs.com/yspm/p/12885610.html