タイトル
1からnまでの番号が付け夜のランプを、N-点灯。
次のように今、2つの動作モードがあります:
- 操作1は、参照をオフにする[L、R]間隔ランプ
- 2オペレーション、オープンラベル[L、R]間隔ランプ
以下Q質問時間は、各クエリは、操作を実行する前記動作クエリフォーマット、L、R、K、Kタイプを行いました。それぞれについて、オープンランプの現在の数を答えるように頼みました。
入力
入力の単一のセット、最初の行は、整数N、第二列整数q(1≤n≤10^9,1≤q≤3・^ 5〜10)が含まれ
それぞれの行の次の行3は、クエリQ、L、R、K(1≤L≤R≤nは、1≤K≤2)の整数を表します。
出力
それぞれについて、行ごとの整数で答えを示して答えるように頼みました。
例
入力
4
6
1 2 1
3 4 1
2 3 2
1 3 2
2 4 1
1 4 2
出力
2
0
2
3
1
4
ソリューション:
オープンスペースの4倍にツリーラインので。しかし、我々は<< 2オープンスペースをMAXN膨大なデータの顔は確かにオーバーフローを開いています。
この時点で、我々はスペースを節約するために、動的処方セグメントツリーを使用する必要があります。(またはディスクリート)
ノードは、それに割り当てられたスペースのみで、または割り当てられていないときに使用される動的なオープンポイントは、n個の大きさは1E9であるような質問には、静的を開くことは確か揚げのための部屋です,,,しかし、あなたは彼を見つけます3E5はまた、少数派で使用される範囲、可視範囲を尋ねたので、私たちは流通空間の範囲を使用するように彼を与えるたび
コード:
1 / * 2 动态开点线段树 3 * / 4の#include <stdio.hに> 5の#include < 文字列・H> 6の#include <iostreamの> 7の#include <アルゴリズム> 8の#include <キュー> 9の#include <ベクトル> 10 使って 名前空間はstdを、 11 CONST INT MAXN = 3E5 + 10 。 12 CONST INT INF = 0x3f3f3f3f 。 13のtypedef 長い 長LL。 14 構造体ノード 15 { 16 int型のL、R&LT、SUM、怠惰; 17 ノード() 18である { 19 、L = 0は、R = 0、SUM = 0、=怠惰0 ; 20である } 21である }、ノード[MAXN * 50 ]; 22である INT CNT = 1。 ; // オープンする点の数 23は、 空隙プッシュダウン(int型 L、INT R&LT、int型 K)// Kは、アレイ内の親ノード番号が 24 { 25 INT MID =(L + R&LT)>> 1 ; 26である IF(L =!R) 27 { 28 であれば(ノード[K] .L!)ノード[K] .L = ++ CNT。 29 もしノード[K] .R = ++(ノード・R [K]!)CNT。 30 31 であれば(ノード[K] .lazy == 2 ) 32 { 33 ノード[ノード[K] .L] .SUM =ノード[ノード[K] .R] .SUM = 0 。 34 } 35 他の 36 { 37 ノード[ノード[K] .L] .SUM =ミッドL + 1 。 38 ノード.SUM = R- [ノード[] .R K] の中間を、 39 } 40 ノード[ノード[K] .L] = .lazy ノード[K] .lazy; 41である ノード[ノード[K]・R] = .lazy ノード[K] .lazy; 42である } 43である ノード[K] .lazy = 0 ; 44 } 45 // セグメントツリーに区間[L、R&LT]内に挿入されている 46である ボイド挿入(int型 L、INT R&LT、INT&K、int型の L、INT R&LT、INT P) 47 { 48 IF(K!)K = CNT ++; // このことは、我々がノードにしたいkに相当します[k]は、このノードが動作 49 // これは我々のオープンポイント動的であるため、ノードを[1]はそのノードが開いてない点が存在しない、ルートノードであります0の初期値 50 IF(L> = R&LT && L <= R&LT) // 我々は次のノードを必要としないため、この条件プッシュダウンを満足する必要がない場合、回答セクションの[L、R]を得ることができる 51は 、{ 52は IF(P == 2)ノード[K] .SUM = 0 ; 53である 他ノード[K] = R&LT .SUM-L + 1 ; 54である ノード[K] .lazy = P; 55 リターン; 56である } 57は、 // 上記決意されない場合、次いで私たちは、あなたがそのサブポイントがうまく変更されていることを確認しなければならないの周りに、再帰的な子ノードkについては、この時間を入力します 58 // すなわち、怠惰な怠け者は0ラベル付けされた 59 IF (ノード[K] .lazy)プッシュダウン(Lを、 R&LT、K); 60 INT MID =(L + R&LT)>> 1 ; 61である IF(MID> =L)を挿入(L、中間、ノード[K]・L、L、R、P)。 62 であれば(MID <R)インサート(中+ 1 、R、ノード[K]・R、L、R、P)。 63 ノード[K] .SUM =ノード[ノード[K] .L] .SUM + ノード[ノード[K] .R] .SUM。 64 } 65 のint main()の 66 { 67 // のprintf( "%D%D \ n"は、ノード[1] .L、ノード[1] .R)。 68 INT N、Q。 69 のscanf(" %D%D "、&N、&Q)。 70 のint、K = 1 。 71 のために(INTは iは= 1、I ++; I <= Q ) 72 { 73 のint L、R、P。 74 のscanf(" %D%D%D "、&L&R&P)。 75 インサート(1 、N、K、L、R、P)。 76 のprintf(" %dの\ N "、N-ノード[ 1 ] .SUM)。 77 } 78 リターン 0 。 79 }