Luo Gu [P1903] [] BZOJ2120 number of colors / maintenance repair queue with Mo [team]

Disclaimer: If you want to reprint, can be explained in the comments directly, thank you! https://blog.csdn.net/SSL_ZYC/article/details/90734111

Subject to the effect:

Topic links:
Luo Gu: https://www.luogu.org/problemnew/show/P1903
BZOJ: https://www.lydsy.com/JudgeOnline/problem.php?id=2120

n n only brush, maintain the following:

  1. Q   L   R Q\ L\ R representative asked from you L L brushes to the second R R brushes brush There are several different colors.
  2. R   P   C o l R\ P\ Col the first P P brushes with a color C o l Col

Ideas:

Beginning to see this exciting topic knocked a block, knocking the last to find c o l 1 0 6 col \ leq 10 ^ 6 rather than 1 0 5 10^5 . . .
Correct answer is with Mo repair team.
If there is no modification operations, then this is the team of Mo board.
Just add modify it.


In fact, the team Mo modifications are violent.
We call each modified record, and then modify the number before each inquiry needed to be recorded. If you are asked i i ratio inquiry i 1 i-1 a few more changes, then put these changes changing for the better, if less then change it back.
In fact, really is violence.

void work(int x,int i)  //要做第x次修改,这次是询问i
{
	if (chg[x].x>=ask[i].l&&chg[x].x<=ask[i].r)  //在区间内修改才有贡献
	{
		cnt[a[chg[x].x]]--;
		if (!cnt[a[chg[x].x]]) sum--;
		if (!cnt[chg[x].val]) sum++;
		cnt[chg[x].val]++; 
	}
	swap(a[chg[x].x],chg[x].val);
	//交换之后,如果下次要改回来时就相当于把现在的值储存到原数组里
}

Mo repair team with the most average complexity is about to take B l o c k = n 3 Block=\sqrt[3]{n} . It proved to be impossible to prove the XD
do not know why I knocked the thief slow mo running team. do not add O f a s t , i n l i n e Ofast,inline , then run 4 s + 4s + . Please Gangster treatise.


Code:

%:pragma GCC optimize("Ofast")
%:pragma GCC optimize("inline")
#include <cmath>
#include <cstdio>
#include <string>
#include <algorithm>
#define rr register
using namespace std;

const int N=50010,M=1000010;
int n,m,s,Q,T,l,r,sum,k,a[N],ans[N],cnt[M],pos[N];
char ch;

int read()
{
	int d=0;
	char ch=getchar();
	while (!isdigit(ch)) ch=getchar();
	while (isdigit(ch))
		d=(d<<3)+(d<<1)+ch-48,ch=getchar();
	return d;
}

void write(int x)
{
	if (x>9) write(x/10);
	putchar(x%10+48);
}

struct Ask
{
	int l,r,id,k;
}ask[N];

struct Change
{
	int x,val;
}chg[N];

bool cmp(Ask x,Ask y)
{
	if (pos[x.l]<pos[y.l]) return 1;
	if (pos[x.l]>pos[y.l]) return 0;
	return x.r<y.r;
}

void del(int x)
{
	cnt[a[x]]--;
	if (!cnt[a[x]]) sum--;
}

void add(int x)
{
	if (!cnt[a[x]]) sum++;
	cnt[a[x]]++;
}

void work(int x,int i)
{
	if (chg[x].x>=ask[i].l&&chg[x].x<=ask[i].r)
	{
		cnt[a[chg[x].x]]--;
		if (!cnt[a[chg[x].x]]) sum--;
		if (!cnt[chg[x].val]) sum++;
		cnt[chg[x].val]++;
	}
	swap(a[chg[x].x],chg[x].val);
}

int main()
{
	n=read(); Q=read();
	T=pow((double)n,(1.0/3.0));
	for (rr int i=1;i<=n;i++)
	{
		a[i]=read();
		pos[i]=(i-1)/T+1;
	}
	for (rr int i=1;i<=Q;i++)
	{
		while (ch=getchar()) if (ch=='Q'||ch=='R') break;
		if (ch=='Q')
		{
			m++;
			ask[m].l=read(); ask[m].r=read();
			ask[m].id=m; ask[m].k=s;
		}
		else
		{
			s++;
			chg[s].x=read(); chg[s].val=read();
		}
	}
	sort(ask+1,ask+1+m,cmp);
	l=1;
	for (rr int i=1;i<=m;i++)
	{
		for (;l<ask[i].l;l++) del(l);
		for (;l>ask[i].l;l--) add(l-1);
		for (;r<ask[i].r;r++) add(r+1);
		for (;r>ask[i].r;r--) del(r);
		for (;k<ask[i].k;k++) work(k+1,i);
		for (;k>ask[i].k;k--) work(k,i);
		ans[ask[i].id]=sum;
	}
	for (rr int i=1;i<=m;i++)
		write(ans[i]),putchar(10);
	return 0;
}

Guess you like

Origin blog.csdn.net/SSL_ZYC/article/details/90734111