[CSP-Sシミュレーション試験]:(小新鮮セグメントツリー)と

タイトル説明

トピック怠惰な人ので何の背景はありませんので。
:$ 0 $の最初完全な無限長$ 01 $配列、各時間範囲$ [のL、R] $動作を選択する、3つの操作がある
$ \弾丸1つの\ Lの\のR&LT $ A $ [L、R] $は。 $ 1 $になるためのすべての要素。
$ \弾丸2 \ L \ R $ A $ [L、R]は$ 0 $にすべての要素を$。
$ \弾丸3 \ L \ R $ A $ [L、R] $すべての要素の排他的$ 1、$。
後、各操作は、$ 0 $での左端の位置を尋ねました。


入力形式

最初の行番号の$ M $は、配列の長さおよび操作の数を表します。
3つの数字一つの操作が記載されている$ TYの\ Lの\器R $、次の$ M $行。


出力フォーマット

合計$ mの$出力ライン、ライン出力は$ iが$ iが$操作の後に回答の数を表します$。


サンプル

サンプル入力:

3
1〜3 4
3 1 6
2 1 3

出力例:

1
3
1


データ範囲とヒント

$ N-順序は$ $ \ MAX(R)$です。
テストポイントの$ 1 \ SIM 4 $:$ N、Mの\は10 ^ 3 $をleqslant。
テストポイントのための$ 5 \ simの6 $:1 $の操作のみ$。
テストポイントの$ 7 \シム10 $:$ 1、$のみ運転。
テストポイントのために$ 11 \ simの15 $:$ N \は10 ^ 5 $をleqslant。
特別な制限:テストポイント$ 16 \ simの20 $のために。
すべてのデータ、$ n個の\ leqslant 10 ^ {ための 18}、m個の\ leqslant 10 ^ 5 $。


問題の解決策

データ範囲を見て、それは離散、離散することは確かであるが、また注意を払う必要がある場合の$ L + 1 $と$ R + 1 $離散。

たったの$ 1,2 $を動作させる場合には、我々は、ツリーラインと直接維持することができます。

だから我々が対処することができますどのようにケース$ 3 $を考えます。

いくつかのセクションが同じであれば、我々は直接それを裏返しすることができ、その後、$ $を返します。

しかし、そうすることは簡単... ​​$ 0101010を言う、カードを交換することができ$シーケンスは$ 3 $、毎回実行する操作で、その後、$ nの^ 2 $に巻き込まれる。

$ A $にしかし、このためにKeduo李ツリーは無関係です質問、外にすることができます。

時間複雑:$ \シータ(N)\ simの\シータ(N ^ 2)$。

期待はスコア:$ $ 100ポイントを。

実際のスコア:$ $ 100ポイント。


コードの時間

#include<bits/stdc++.h>
#define L(x) x<<1
#define R(x) x<<1|1
#define inf 0x3f3f3f3f
using namespace std;
map<long long,long long> mp;
struct rec{int ty;long long l,r;}e[200001];
int m;
int n;
long long pre[5000000];
long long trsam[10000000],trans[10000000],lz[10000000];
void pushup(int x)
{
	trans[x]=min(trans[L(x)],trans[R(x)]);
	trsam[x]=(trsam[L(x)]==trsam[R(x)])?trsam[L(x)]:-1;
}
void pushdown(int x,int l,int r)
{
	if(lz[x]==-1)return;
	int mid=(l+r)>>1;
	lz[L(x)]=lz[R(x)]=trsam[L(x)]=trsam[R(x)]=lz[x];
	if(!trsam[L(x)])trans[L(x)]=l;
	else trans[L(x)]=inf;
	if(!trsam[R(x)])trans[R(x)]=mid+1;
	else trans[R(x)]=inf;
	lz[x]=-1;
}
void build(int x,int l,int r)
{
	trans[x]=inf;
	lz[x]=-1;
	if(l==r)
	{
		trans[x]=l;
		return;
	}
	int mid=(l+r)>>1;
	build(L(x),l,mid);
	build(R(x),mid+1,r);
	pushup(x);
}
void change(int x,int l,int r,int L,int R,int opt)
{
	if(R<l||r<L)return;
	if(L<=l&&r<=R&&trsam[x]!=-1)
	{
		switch(opt)
		{
			case 1:trsam[x]=1;lz[x]=1;break;
			case 2:trsam[x]=0;lz[x]=0;break;
			case 3:trsam[x]^=1;lz[x]=trsam[x];break;
		}
		if(!trsam[x])trans[x]=l;
		else trans[x]=inf;
		return;
	}
	int mid=(l+r)>>1;
	pushdown(x,l,r);
	change(L(x),l,mid,L,R,opt);
	change(R(x),mid+1,r,L,R,opt);
	pushup(x);
}
int main()
{
	scanf("%d",&m);
	for(int i=1;i<=m;i++)
		scanf("%d%lld%lld",&e[i].ty,&e[i].l,&e[i].r);
	for(int i=1;i<=m;++i)
	{
		pre[i*4-3]=e[i].l, pre[i*4-2]=e[i].r;
		pre[i*4-1]=e[i].l+1, pre[i*4]=e[i].r+1;
	}
	pre[m*4+1]=1;
	sort(pre+1,pre+m*4+2);
	n=unique(pre+1,pre+m*4+2)-pre-1;
	for(int i=1;i<=m;++i)
	{
		mp[lower_bound(pre+1,pre+n+1,e[i].r+1)-pre]=e[i].r+1;
		mp[lower_bound(pre+1,pre+n+1,e[i].l+1)-pre]=e[i].l+1;
		long long now=e[i].l;
		e[i].l=lower_bound(pre+1,pre+n+1,e[i].l)-pre;
		mp[e[i].l]=now;
		now=e[i].r;
		e[i].r=lower_bound(pre+1,pre+n+1,e[i].r)-pre;
		mp[e[i].r]=now;
	}
	mp[1]=1;
	build(1,1,n);
	for(int i=1;i<=m;++i)
	{
		change(1,1,n,e[i].l,e[i].r,e[i].ty);
		printf("%lld\n",mp[trans[1]]);
	}
	return 0;
}

rp++

おすすめ

転載: www.cnblogs.com/wzc521/p/11615873.html