件名の説明:
D.興味深いアレイ
試験あたり制限時間
1秒
テスト当たりのメモリ限界
256メガバイトの
入力
標準入力
出力
標準出力
我々は、[1]、[2]、...、nは負でない整数のアレイと呼ぶことにしますn]は面白い、それはm個の制約を満たしているかどうか。それらの制約のi番目の値はQIに等しくなければならないことを意味する三つの整数のリチウム、RI、チー(1≤のLi≤RIさ≤N)から成ります。
あなたの仕事は、そのような配列が存在しないn個の要素または状態のいずれかの興味深い配列を見つけることです。
式x&yはと数字のxとyのビット単位を意味しています。「および」として-プログラミング言語C ++、JavaやPythonでは、この操作はPascalで、「&」として表現されます。
入力
配列内の要素の数と制限の数-最初の行は二つの整数N、M(105≤1≤N、105≤1≤M)を含みます。
次のm行の各々は、i番目の限界を説明する三つの整数のリチウム、RI、チー(1≤のLi≤RIさ≤nは、0≤チー<230)を含みます。
出力
興味深い配列は、存在する場合、(引用符なし)最初の行のプリント「YES」で、2行目の印刷のn integersa [1]、[2]、...、[N](0≤[ I興味深い配列をdecribing] <230)。複数回答がある場合は、それらのいずれかを印刷します。
興味深い配列は、(引用符なし)、プリント「NO」は、単一の行に存在しない場合。
例
入力
3 1
1 3 3
の出力
YES
3 3 3
入力
3 2
1 3 3
1 3 2
出力
NO
アイデア:
セクションと関連する問題は、セグメントツリーと考えることができます。この質問は、構築、配列の数によって再び時間と時間を制限することです。例えばつまりバイナリ表現における結果R&Qの数にl番目、および結果がAである場合は、1つの結果場合、すべてのビットの数は、セクションのすべてでありますゼロ、この間隔に0ビットのその後少なくとも数。
始まり:すべての瞬間のために1のためにこの1上の間隔上のすべての数字を知るために、どの範囲がゼロとゼロの数のいずれかを知りません。二次元ベクターを構築したいと思い、アレイの数は、バイナリ暴力が可能な結果を解決する表します。しかし、それは(これはこんにゃくである私のために少し難しいプログラミング)操作は非常に複雑であると思われる、またタイムアウトになることがあります。
最後に:組み合わせるために、問題を見てみましょう、ツリーラインを考えてみましょう。区間[L、R]、仮定及び間隔に3(試料1)、次いで、各数値の結果(合計アレイはセグメントツリーを実装する)のツリーラインのリーフノード、合計を開始[I]は= 0、制限時に、和[K]と| = Q [i]は、(Q [i]が示すと結果)、すなわち、使用時または動作時、我々は、物品を満たすため和[k]を構築することができます以前の満足時にだけ設定条件は、後になる可能性があるため、すべての制限は、[i]の間隔とあれば、まだのqに等しい与えられた1つの上限条件を照会するには、完成していた制限は、制限は、それが矛盾する制約はないので、それは、相反する両者の限界でその変化を示す変化、それらの数が等しいか、または構造のいずれかでナンバーワンは同じではない構成されるべきです。
需要間隔とセグメントツリーテンプレートマイナーな変更で。具体的には、
突き上げ(K){和[K ] =和[K << 1] +和[K << 1 | 1] プラス変更し、問い合わせ操作でと少し長く考え、それはそうとしない結果を返しますあまりにも、データ範囲(以下2 ^ 30)のタイトルで述べたように、I = 2 ^ 30-1の使用に、ANSを配置する+ =···I&=···結果を返します。
注意は、時間のプッシュダウンされ、そしてどのように、もう一つを返すように結果を返すために:あなたは30-1 2 << 2 ^ 30-1であると思いますか?間違いました!演算子の優先順位は、(2 << 30)を書き込むことに注意してください-1
知識ポイント:セグメントツリー
コード:
1の#include <iostreamの> 2 の#define max_n 100005 3 使用して 名前空間STDを、 4 int型の和[max_n << 2 ]。 5 INT LZ [max_n << 2 ]。 6 INTをL [max_n]。 7 のint R [max_n]。 8 int型Q [max_n]。 9 INT N。 10 INT M。 11は int型Iを。 12 ボイド押し上げ(int型K) 13 { 14 和[K] =和[K << 1]&合計[K << 1 | 1 ]。 15 } 16 空隙プッシュダウン(int型 K、int型 LN、INT RN) 17 { 18 であれば(LZ [K]) 19 { 20 和[K << 1 ] | = LZ [K]。 21 合計[K << 1 | 1 ] | = LZ [K]。 22の LZ [K << 1 ] | = LZ [K]。 23の LZ [K << 1 | 1 ] | = LZ [K]。 24 LZ [K] = 0 ; 25 } 26 } 27 空隙ビルド(int型 K、int型の L、INT R) 28 { 29の LZ [K] = 0 ; 30 であれば(L == R) 31 { 32 和[K] = 0 ; 33 リターン; 34 } 35 INT半ば=(L + R)>> 1 。 36 ビルド(K << 1 、L、MID)。 37 ビルド(K << 1 |1、中間+ 1 、R)。 38 押上(K)。 39 } 40 空隙更新(int型 K、int型の L、INT R、int型の L、INT R、INT ヴァル) 41 { 42の 場合(L <= 1 && R <= R) 43 { 44 和[K] | = ヴァル。 45の LZ [K] | = ヴァル。 46 リターン; 47 } 48 INT半ば=(L + R)/ 2 。 49 INTLN =半ばL + 1 。 50 int型 RN = R- 半ば; 51 プッシュダウン(K、LN、RN)。 52 であれば(L <= MID)更新(K << 1 、L、R、L、中間、ヴァル)。 53 であれば(MID <R)更新(K << 1 | 1、L、R、中間+ 1 、R、ヴァル)。 54 押上(K)。 55 } 56 INTクエリ(INT K、int型の L、INT R、INT L、INT R) 57 { 58 であれば(L <= 1 && R <= R) 59 { 60 // COUT << "K" << K << "" <<和[K] << ENDL。 61 リターン和[K]。 62 } 63 INT半ば=(L + R)>> 1 。 64 INT LN =ミッドL + 1 。 65 int型 RN = R- 半ば; 66 プッシュダウン(K、LN、RN)。 67 長い 長い I =(長い 長い)(2 << 30) - 1 。 68 であれば(L <= MID)I = I&クエリ(K << 1 、L、R、L、MID)。 69 // coutの<< 70 であれば(MID <R)I = I&クエリ(K << 1 | 1、L、R、中間+ 1 、R)。 71 押上(K)。 72 // coutの<< "侯" << I <<てendl; 73 リターンI; 74 } 75 のint main()の 76 { 77 CIN >> N >> M。 78 ビルド(1、1 、N) 79 のためには、(int型 i = 0 ; iがm <; iは++ ) 80 { 81 CIN >> L [I] >> R [I] >> Q [i]は、 アップデート(1、L [i]は、R [i]は、1 、N、Q [I])。 83 } 84 のための(int型 i = 0 ; iがm <; iは++ ) 85 { 86 INT ANS =クエリ(1、L [i]は、R [i]は、1 、N)。 87 場合(ANS =!Q [I]) 88 { 89 COUT << " NO " << ENDL。 90 リターン 0 ; 91 } 92 } 93 COUT << "YES " << ENDL; 94 用の(int型 i = 1 ; iがn = <; iは++ ) 95 { 96 COUT <<クエリ(1、I、I、1、N)<< " " ; 97 } 98 リターン 0 。 99 }