[CSP-Sシミュレーション試験]:ドーナツ(セグメントツリー)

タイトル説明

  $ D $先生は、偉大なドーナツメーカーです。今日、彼は日の出前に台所でドーナツを作るために準備ができています。$ N完成氏はインスタントの$ D $はドーナツを$。しかし、これらのドーナツ装飾ドーナツの販売になることができ、タスクのすべての種類を通過する必要が:クリームフィリングは、とてもかわいい、カラフルなものやトッピング、チョコレートに浸しました。
  、$ K $装飾タスクは、タスクは$ K $を$ 1 $の番号が付けられており、それぞれのドーナツは$ 1から$ K $クエストに厳密に従ったものでなければならない、2 ...、K $一回だけ注文を完了するために、販売アイテムとなっています。
  一度、各タスクの装飾を完了するために、上の行に$ N $ミスタードーナツへの$ D $は、彼が意図そうです。しかし、昨夜遅くまで滞在し、氏は$ D $は、各タスク連続体の一部だけドーナツを飾りました。これは明らかに間違いである!それだけで、彼はまた、同じタスクを複数回行うことができない、タスクの順序が混乱しています。
  彼はそれらを捨てる必要がありますので、販売アイテムとして、飾らドーナツを通じて正しい流れを提供することはできませんではありません。幸いなことに、データは、彼が行っていた一連のタスクに記録されています。データは、以下の情報が含まれています。各タスクについては、ドーナツ装飾連続の$ [のL、R] $のIDを $ とタスク\ X $。
  ドーナツの数は、ディスプレイケースの販売実績データとして与えられた答えを表示することができます引用し、プログラムを書きます。


入力形式

最初の二つの整数$ N $ K $のラインと$、$ N $はドーナツと$ K $タスクを表明しました。
2行目は整数$性T $、$ D氏$は$ T $装飾間隔の完了に続いて表します。
区間$ [L_iを、R_iを] $ $ $ X_I装飾タスクの$ $ ID完成ドーナツを表すそれぞれ3つの正の整数$ L_iを、R_iを、X_Iの$、その後の$ T $線、。


出力フォーマット

整数表示ドーナツの数として表すことができます。


サンプル

サンプル入力:

5 3
5
2 3 1
1 3 2
4 5 1
2 3 4
3 5 2

出力例:

1


データ範囲とヒント

サンプルは説明しました:

$ 1 $ドーナツので断念し、$ 3 $ドーナツタスクは$ 2 $ 2 $を放棄し、$回完了繰り返される$ 1 $ 2 $ $のタスクを完了するためのタスクを完了しませんでした!$ 4 $ドーナツタスク、その後、$ 3 $ 2 $ $を完了するためにタスクを完了するために、捨てられました!$ 5 $ドーナツは、$ 3 $は、捨てられたタスクを完了しませんでした!したがって、唯一の$ 2 $を表示することができます。

データ範囲:

$ 40 \%の$データ、$ N、K、T \のため leqslant 5,000 $
追加$ 20 \%の$ aのデータ、$ K \ 100 $ leqslant
\%$ A、$ L_iを= R_iを$追加の$ 10のデータを
$ 100 \ため%の$データ、$ 1 \ leqslant N、K 、Tの\ leqslant 200,000 X_I \ leqslant K、1 \ leqslant L_iを\ leqslant R_iを\ leqslant Nの$


問題の解決策

どうやらツリーライン、我々は維持する方法を検討します。

怠惰な二つのマーカー、それぞれ、上端及び下端、$ 1 - $フラグは$、全く遅延がないことを示す - 2 $このセクションは、有効なもはやでき表します。

最後に、全体のツリーは、統計的な答えながら実行することができます。

時間の複雑さ:$ \シータ$(N N + Tを記録\ \ Nを記録)。

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

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


コードの時間

#include <ビット/ STDC ++。H>
#define L(x)は、x << 1
#define R(x)は、x << 1 | 1
名前空間stdを使用。
整数N、K、T。
INT [1000000] TR、LZ1 [1000000]、LZ2 [1000000]。
int型の年。
空のビルド(int型のx、int型のL、int型R)
{
	LZ1 [X] = LZ2 [X] =  -  2。
	(L == R)戻った場合。
	INT半ば=(L + R)>> 1。
	ビルド(L(x)は、L、MID)。
	ビルド(R(x)は、中間+ 1、R)。
}
空プッシュダウン(int型x)は、
{
	IF(LZ1 [X] ==  -  2)リターン。
	if(lz1[x]==-1)
	{
		tr[L(x)]=tr[R(x)]=lz1[L(x)]=lz1[R(x)]=lz2[L(x)]=lz2[R(x)]=-1;
		return;
	}
	if(tr[L(x)]!=-1)
	{
		if(tr[L(x)]+1==lz1[x])tr[L(x)]=lz2[x];
		else tr[L(x)]=-1;
	}
	if(tr[R(x)]!=-1)
	{
		if(tr[R(x)]+1==lz1[x])tr[R(x)]=lz2[x];
		else tr[R(x)]=-1;
	}
	if(lz1[L(x)]!=-1)
	{
		if(lz1[L(x)]==-2){lz1[L(x)]=lz1[x];lz2[L(x)]=lz2[x];}
		else if(lz2[L(x)]+1==lz1[x])lz2[L(x)]=lz2[x];
		else lz1[L(x)]=lz2[L(x)]=-1;
	}
	if(lz1[R(x)]!=-1)
	{
		if(lz1[R(x)]==-2){lz1[R(x)]=lz1[x];lz2[R(x)]=lz2[x];}
		else if(lz2[R(x)]+1==lz1[x])lz2[R(x)]=lz2[x];
		else lz1[R(x)]=lz2[R(x)]=-1;
	}
	lz1[x]=lz2[x]=-2;
}
void change(int x,int l,int r,int L,int R,int w)
{
	if(r<L||R<l)return;
	if(L<=l&&r<=R)
	{
		if(tr[x]!=-1)
		{
			if(tr[x]+1==w)tr[x]++;
			else tr[x]=-1;
		}
		if(lz1[x]!=-1)
		{
			if(lz1[x]==-2)lz1[x]=lz2[x]=w;
			else if(lz2[x]+1==w)lz2[x]++;
			else lz1[x]=lz2[x]=-1;
		}
		return;
	}
	pushdown(x);
	int mid=(l+r)>>1;
	change(L(x),l,mid,L,R,w);
	change(R(x),mid+1,r,L,R,w);
}
void ask(int x,int l,int r)
{
	if(l==r)
	{
		if(tr[x]==K)ans++;
		return;
	}
	pushdown(x);
	int mid=(l+r)>>1;
	ask(L(x),l,mid);
	ask(R(x),mid+1,r);
}
int main()
{
	scanf("%d%d%d",&N,&K,&T);
	build(1,1,N);
	while(T--)
	{
		int l,r,x;
		scanf("%d%d%d",&l,&r,&x);
		change(1,1,N,l,r,x);
	}
	ask(1,1,N);
	printf("%d",ans);
	return 0;
}

rp++

おすすめ

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