莫队 RE 求助
查看原帖
莫队 RE 求助
232460
xiaoqian02楼主2023/8/3 13:21

提交了很多次,每次都 RE。

甚至把数组大小开到 5×1055 \times 10^5 也还是炸(题目只有 5×1045 \times 10^4)

求助(从代码里可以很容易地看到数组开得远大于正常,但正常开数组也会炸掉)。

Code:

#include<bits/stdc++.h>
using namespace std;
void IOS()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	return;
}
struct Qst
{
	int l,r,nb;//l,r 是左右端点,nb 是编号
}qs[500005];
int n,q,l,r,k,cnt,a[500005],nm[500005];
int bll[1005],blr[1005],fr[500005];
long long sm,ans[500005];
bool cmp(Qst a,Qst b)
{
	return fr[a.l]<fr[b.l]||(fr[a.l]==fr[b.l]&&a.r<=b.r);
}
void del(int p)//删除
{
	sm-=(2*nm[a[p]]-1);
	nm[a[p]]--;
	return;
}
void add(int p)//添加
{
	sm+=(2*nm[a[p]]+1);
	nm[a[p]]++;
	return;
}
int main()
{
	IOS();
	cin>>n>>q>>l;//k 实际上应该没用,随便读了一下
	for(int i=1;i<=n;i++) cin>>a[i];
	l=1;
	cnt=sqrt(n);
	while(l+cnt-1<=n)
	{
		bll[++k]=l;
		blr[k]=l+cnt-1;
		for(int i=bll[k];i<=blr[k];i++) fr[i]=k;
		l+=cnt;
	}
	if(l<=n)
	{
		bll[++k]=l;
		blr[k]=n;
		for(int i=bll[k];i<=blr[k];i++) fr[i]=k;
	}//以上一大段都是分块
	l=1,r=0;
	for(int i=1;i<=q;i++)
	{
		cin>>qs[i].l>>qs[i].r;
		qs[i].nb=i;//离线统计下来
	}
	sort(qs+1,qs+q+1,cmp);
	for(int i=1;i<=q;i++)//标准莫队
	{
		while(l<qs[i].l) del(l),l++;
		while(l>qs[i].l) l--,add(l);
		while(r>qs[i].r) del(r),r--;
		while(r<qs[i].r) r++,add(r);
		ans[qs[i].nb]=sm;
	}
	for(int i=1;i<=q;i++) cout<<ans[i]<<endl;
	return 0;
}
2023/8/3 13:21
加载中...