带修莫队TLE求调
查看原帖
带修莫队TLE求调
95170
Tune_楼主2023/7/22 16:11

或者有没有其它更好的做法?

#include<bits/stdc++.h>
using namespace std;
#include<bits/stdc++.h>
using namespace std;
int n,m,cntq=0,cntc=0;
int read()
{
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0',c=getchar();}
    return x*f;
}
struct quer
{
	int l,r,pre,id;
}q[133335];
struct chan
{
	int pos,col;
}c[1333335];
int p[1333335],ans[1333336],a[1333336],vis[1333336],s=0;
bool cmp(quer x,quer y)
{
	if(p[x.l]!=p[y.l])
		return p[x.l]<p[y.l];
	else
	   	if(p[x.r]!=p[y.r])
            return x.r<y.r;
        else
            return x.pre<y.pre;
}
void add(int x)
{
	if(++vis[a[x]]==1)
		s++;
}
void sub(int x)
{
	if(--vis[a[x]]==0)
		s--;
}
void wor(int po,int x)
{
	if(c[po].pos>=q[x].l&&c[po].pos<=q[x].r)
	{
		if(--vis[a[c[po].pos]]==0)
			s--;
		if(++vis[c[po].col]==1)
			s++;		
	}
	swap(c[po].col,a[c[po].pos]);
}
void mo()
{
	int l=1,r=0,now=0;
	for(int i=1;i<=cntq;i++)
	{
		while(q[i].l<l)
			add(--l);
		while(q[i].r>r)
			add(++r);
		while(q[i].l>l)
			sub(l++);
		while(q[i].r<r)
			sub(r--);
		while(q[i].pre>now)
			wor(++now,i);
		while(q[i].pre<now)
			wor(now--,i);
		ans[q[i].id]=s; 
	}
	for(int i=1;i<=cntq;i++)
		printf("%d\n",ans[i]);
}
int main()
{
	scanf("%d%d",&n,&m);
	int kuai=sqrt(n);
	for(int i=1;i<=n;i++)
	{
        p[i]=(i-1)/kuai+1;
		a[i]=read();
    }
	while(m--)
	{
		char ci;
		scanf("\n");
		if(getchar()=='Q')
		{
			++cntq;
			q[cntq].l=read();
            q[cntq].r=read();
			q[cntq].id=cntq;
			q[cntq].pre=cntc;
		}
		else
		{
			++cntc;
			c[cntc].pos=read();
            c[cntc].col=read();
		}
	}
	sort(q+1,q+cntq+1,cmp);
	mo();
	return 0;
}
2023/7/22 16:11
加载中...