羅区[P1903] [] BZOJ2120のMoと色/メンテナンス・修理キューの数[チーム]

免責事項:あなたが転載したい場合は、直接コメントで説明することができ、ありがとうございました!https://blog.csdn.net/SSL_ZYC/article/details/90734111

効果の件名:

トピックリンク:
羅区:https://www.luogu.org/problemnew/show/P1903
BZOJ:https://www.lydsy.com/JudgeOnline/problem.php?id=2120

n n個 だけブラシは、以下を維持します:

  1. Q   L   R Q \ Lの\のR 代表があなたから尋ね L L 第二のブラシ R R いくつかの異なる色がありますブラシをブラシ。
  2. R   P   C o l R \ P \コル 最初 P P 色でブラシ C o l コル

アイデア:

見つけるために最後ノック、このエキサイティングなトピックは、ブロックをノック見始め c o l 1 0 6 コル\の当量10 ^ 6 ではなく、 1 0 5 10 ^ 5
正解は、Moの修理チームです。
何の変更操作がない場合、これは、MOボードのチームです。
ちょうどそれを変更、追加。


実際には、チームのMo変更は暴力的です。
私たちは、それぞれ変更されたレコードを呼び出し、その後、記録されるために必要な各お問い合わせの前に番号を変更します。あなたは尋ねている場合 i 比のお問い合わせ i 1 I-1 未満戻ってそれを変更した場合、さらにいくつかの変更は、その後、良い方向に変え、これらの変更を置きます。
実際には、本当に暴力です。

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修理チームが取るしようとしています B l o c k = n 3 ブロック= \ SQRT [3] {N} それはXDを証明することは不可能であることが証明され
、私は泥棒遅いMOランニングチームをノックした理由を知りません。無し O f a s t , i n l i n e Ofast、インライン 、その後、実行します 4 s + 4S + 論文をギャングしてください。


コード:

%: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;
}

おすすめ

転載: blog.csdn.net/SSL_ZYC/article/details/90734111