分块莫队——维护队列

题目描述

样例输入

2 3
1 2
Q 1 2
R 1 2
Q 1 2

样例输出

2
1

题目分析

首先它是一个离线莫队(在线超时QAQ)
离线首先存下它所有的询问和修改,分别存,询问要存下是第几次,以便后续输出,还要存下时间是第几个命令,比较询问和修改的时间,相应的变换颜色,最后整体输出

#include<bits/stdc++.h>
using namespace std;

const int maxn=133340;
const int maxm=1e6+10;
int a[maxn],n,m;
int l=1,r,col[maxm],ans,cnt[maxn],sq;
int bl[maxn];
struct node
{
	int l,r,id,t;
}q[maxn];
struct stu
{
	int pos,col,t;
}rp[maxn];

bool cmp(node A,node B)
{
	if(bl[A.l]!=bl[B.l]) return bl[A.l]<bl[B.l];
	if(bl[A.r]!=bl[B.r]) return bl[A.r]>bl[B.r];
	return A.t<B.t;
}

void add(int x)
{
	if(!col[x]) ans++;
	col[x]++;
}

void del(int x)
{
	col[x]--;
	if(!col[x]) ans--;
}

int main()
{
	scanf("%d%d",&n,&m);
	sq=pow(n,2.0/3.0);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
		bl[i]=i/sq+1;
	}
	int x,y,t=0;
	int xg=0,cx=0;
	char ch;
	for(int i=1;i<=m;i++)
	{
		scanf(" %c %d%d",&ch,&x,&y);
		if(ch=='Q') cx++,q[cx]=node{x,y,cx,xg};
		else xg++,rp[xg]=stu{x,y,xg};
	}
	sort(q+1,q+1+cx,cmp);
	for(int i=1;i<=cx;i++)
	{
		while(q[i].l<l)
		{
			l--;
			add(a[l]);
		}
		while(q[i].l>l)
		{
			del(a[l]);
			l++;
		}
		while(q[i].r<r)
		{
			del(a[r]);
			r--;
		}
		while(q[i].r>r)
		{
			r++;
			add(a[r]);
		}
		while(q[i].t>t)
		{
			t++;
			if(rp[t].pos>=l&&rp[t].pos<=r)
			{
				del(a[rp[t].pos]);
				add(rp[t].col);
			}
			swap(a[rp[t].pos],rp[t].col);
		}
		while(q[i].t<t)
		{
			if(rp[t].pos>=l&&rp[t].pos<=r)
			{
				del(a[rp[t].pos]);
				add(rp[t].col);
			}
			swap(a[rp[t].pos],rp[t].col);
			t--;
		}
		cnt[q[i].id]=ans;
	}
	for(int i=1;i<=cx;i++)
	{
		printf("%d\n",cnt[i]);
	}
	
	return 0;
}
posted @ 2024-04-23 11:40  晨曦ccx  阅读(19)  评论(0)    收藏  举报
浏览器标题切换
浏览器标题切换end