【做题记录】统计区间(哈希/扫描线)

交题链接

给你一个长度为 (n(nle 10^6)) 的序列,其中每个元素都在 ([1,n]) 范围中。

询问有多少个区间满足区间中的元素都恰好出现 (2) 次。

( exttt{solution}~ exttt{1:}) 哈希

我们考虑如果元素个数 (le 64) 时我们怎么做:

给每个元素分配一个二进制位,记录到当前为止的异或和,同时用 map 记录同为这个异或和的位置数量(当然要保证出现位置在这个元素上上次出现以后),并累加答案。

但是如果元素个数过多怎么办?答案是哈希!!!

我们给每个元素随机附上一个值,向上面一样添加和求出答案。

事实证明在随机赋值是正确率是非常高的。

$ exttt{code}$
#define Maxn 1000005
typedef unsigned long long ll;
int n,pos;
ll ans;
int a[Maxn],llast[Maxn],last[Maxn];
ll ha[Maxn],pre[Maxn];
unordered_map<ll,int> cnt;
int main()
{
	 srand(time(0));
	 n=rd();
	 for(int i=1;i<=n;i++) a[i]=rd(),ha[i]=1llu*rand()*rand()*rand()*rand()*rand()*rand();
	 cnt[0]++;
	 for(int i=1;i<=n;i++)
	 {
	 	 while(pos<llast[a[i]]) cnt[pre[pos]]--,pos++;
	 	 llast[a[i]]=last[a[i]],last[a[i]]=i;
	 	 pre[i]=pre[i-1]^ha[a[i]];
	 	 ans+=cnt[pre[i]];
	 	 cnt[pre[i]]++;
	 }
	 printf("%llu
",ans);
	 return 0;
}

( exttt{solution}~ exttt{2:}) 扫描线

我们记 (Pos(i,1/2/3)) 表示当前右端点以左,离数字 (i) 距离第 (1,2,3) 远的位置。

易知当左端点位于 ([1,Pos(3)],[Pos(2)+1,Pos(1)]) 时答案不合法,所有不合法位置的并集就是所有不合法位置。

可以通过总位置减去不合法位置来求出合法位置,因此变成了一道区间染色问题。

我们通常用扫描线(不下传标记)来维护区间是否被染色,这题也可以这么维护。

$ exttt{code}$
#define Maxn 1000005
typedef long long ll;
int n,ans;
int a[Maxn],Last[Maxn][3];
struct TREE{ int laz,sum; }tree[Maxn<<3];
inline void pushup(int p,int nl,int nr)
{
	 if(tree[p].laz>0) tree[p].sum=nr-nl+1;
	 else tree[p].sum=tree[p<<1].sum+tree[p<<1|1].sum;
}
void add(int p,int nl,int nr,int l,int r,int k)
{
	 if(l>r) return;
	 if(nl>=l && nr<=r) { tree[p].laz+=k,pushup(p,nl,nr); return; }
	 int mid=(nl+nr)>>1;
	 if(mid>=l) add(p<<1,nl,mid,l,r,k);
	 if(mid<r) add(p<<1|1,mid+1,nr,l,r,k);
	 pushup(p,nl,nr);
}
int main()
{
	 n=rd();
	 for(int i=1;i<=n;i++) a[i]=rd();
	 for(int i=1;i<=n;i++)
	 {
	 	 add(1,1,n,1,Last[a[i]][2],-1);
		 add(1,1,n,Last[a[i]][1]+1,Last[a[i]][0],-1);
		 Last[a[i]][2]=Last[a[i]][1];
		 Last[a[i]][1]=Last[a[i]][0];
		 Last[a[i]][0]=i;
		 add(1,1,n,1,Last[a[i]][2],1);
		 add(1,1,n,Last[a[i]][1]+1,Last[a[i]][0],1);
		 ans+=i-tree[1].sum;
	 }
	 printf("%d
",ans);
	 return 0;
}
原文地址:https://www.cnblogs.com/EricQian/p/15500546.html