まず第一に、$ kの$改正ツリーは$ 2 ^ k個の$の木を持って見ることは容易であるので、暴力は間違いなくだけ20ptsである私がやることではありません
したがって、我々は$ 2 ^ {K} $ツリーのメンテナンスが木になりたいです。ハチソン$ P_o $ $マークの木で$確率O、答えは$ \ {合計P_o} * 2です ^ {K} $。そこにマークされている$プッシュダウン$、それはそれとその祖先限り、アクセスされたノードが存在するので、しかし、それがマークされますので、我々は$ O $を記録する必要があると$ $ Oの祖先が持っています少なくともマークされた確率$ Pf_o $
今、私たちは、各ノードの変化カテゴリに影響を与えます:
マーキングノード1
修飾は、$ 1 $マークの確率、不変の他の半分の確率、$ P_o = \ FRAC {P_o + 1} {2} $、同様に、$ Pf_oがあり、フラグをヒットした半分の木、で発生します= \ FRAC {Pf_o + 1} {2} $。
2. $ $の訪問を変更されていますが、ノードのマークをヒットしませんでした
変更は、ツリー、その祖先の半分に発生し、他のすべての半分変わらず、押下されマークを付けます。従って$ P_o = \ FRAC {P_o} {2}、Pf_o = \ FRAC {Pf_o} {2} $。
3. $のプッシュダウン$訪問ですが、$ $ノードへのアクセスを変更しません
$ Pf_o $その不変(それとプッシュ先祖との間は、全て同じ押さない)、しかし限りタグ祖先として、それ以来、$ $プッシュダウンマークを取る$ P_o = \ FRAC {P_o + Pf_o} {2 SO } $。
4.ノードのサブツリーをマーキング
その祖先そう$ Pf_o = \ FRAC {Pf_o + 1} {2} $、マークされなければならない$ P_o $間違いなくその不変が、変更後、。
ノードのこのクラスは、$ O(N)$番目を有することができるので、我々は直接変更することはできないが、$ \ FRACによって発見実際に変更することができる{1} {2 } プラス$ $ \ FRAC {1} {2 } 以下のようなので、$、ツリーライン2、その上に怠惰なメンテナンスマーク
#include <cstdioを> のtypedef 長い ロングLL、 CONST INT MOD = 998 244 353 ; のconst int型 INV2 = 499 122 177 ; // 逆元2が頻繁に使用され、ダウン維持する のconst int型 N = 100050、中国; チャー [たRB 。1 << 21です ]、* S、T *、WB [ 1。 << 21である]; INT - WP = 1。; インラインチャー GC(){ 戻り T(T =(S = rBの)+関数fread(RB、Sを&& == 1。 、1 << 21は、 ?STDIN)、S == T) EOF:* S ++;} インラインボイドフラッシュ(){関数fwrite(WB、1、WP + 1、STDOUT); WP = - 1 ;} インラインボイド PC(チャー C){ 場合(WP + 1 ==(1 << 21))のフラッシュ() ; WB [++ WP = Cを;} インラインint型RD(){ チャー C = GC()。 一方、(C < 48 || C> 57)C = GC()。 INT X = C&15 。 用(C = GC(); C> = 48個の && C <= 57、C = GC())x =(x <<3)+(X << 1)+(C&15 )。 リターンのx; } 短い BUF [ 15 ]。 インラインボイド重量(INT X){ 短い L = - 1 。 一方、(X> 9 ){ BUF [ ++ L] = X%10 。 X / = 10 。 } PC(X | 48 )。 一方、(L> = 0)PC(BUF [1 - ] | 48 )。 PC(' \ nを' ); } のInt P [N << 2 ]、PF [N << 2 ]、のMuLV [N << 2 ]、ADDV [N << 2 ]、SUM [<< N 3 ]、X、Y; // このリーフノードでそう余分に大きな和を開くために、押し上げます書き込ま ボイドビルド(INT O、INT L、INT R&LT){ MuLVに[O] = 1 ; IF(L < R&LT){ int型 << LC = O 1。、LC RC = | 1、M = L + R&LT >> 1 ; (LC、L、M)を構築し;(RC、Mビルド +を1 、R&LT); } } インラインボイド突き上げ(INT O){ int型 LC = O << 1、RC = LC | 1 ; 和[O] =((LL)p [O] +和[LC] +和[RC])%MOD。 } インラインボイドプッシュダウン(INT O){ int型 LC = O << 1、RC = LC | 1 ; もし(!のMuLV [O] = 1 ){ たMuLV [LC] =(LL)のMuLV [LC] *のMuLV [O]%MOD; ADDV [LC] =(LL)ADDV [LC] *のMuLV [O]%MOD ; PF [LC] =(LL)PF [LC] *のMuLV [O]%MOD。 MuLV [RC] =(LL)のMuLV [RC] *のMuLV [O]%MOD; ADDV [RC] =(LL)ADDV [RC] *のMuLV [O]%MOD; PF [RC] =(LL)のPF [ RC] *のMuLV [O]%のMOD。 MuLVに[O] = 1 ; } もし(ADDV [O]){ もし、((ADDV [LC] + = ADDV [O])> = MOD)ADDV [LC] - = MOD。もし((PF [LC] + = ADDV [O])> = MOD)PF [LC] - = MOD。 もし((ADDV [RC] + = ADDV [O])> = MOD)ADDV [RC] - = MOD。もし((PF [RC] + = ADDV [O])> = MOD)PF [RC] - = MOD。 ADDV [O] = 0 ; } } ボイド更新(int型、O INTの L、INT R){ 場合(X <= L && Y> = R){ // 第1类 P [O] =((LL)p [O] * INV2 + INV2)%モッズ; PF [O] =((LL)PF [O] * INV2 + INV2)%MOD。 MuLVに[O]=(LL)のMuLV [O] *%INV2 MOD; ADDV [O] =((LL)ADDV [O] + * INV2 INV2)%MOD; // プレー遅延マークなどの修飾クラス4 } 他{ int型の LC << O = 1、LC RC = | 1、M = L + R&LT >> 1 ; プッシュダウン(O); IF(X <= M)更新(LC、L、M); 他{ P [LC] =( (LL)P [LC] * INV2 +(LL)PF [LC] * INV2)%MOD; 押し上げ(LC); } // クラス3。 IF(Y> M)アップデート(RC、M + 1 、R&LT)、 他{ P [RC]=((LL)P [RC] * INV2 +(LL)PF [RC] * INV2)%MOD; 押し上げ(RC); } P [O] =(LL)P [O] * INV2の%MOD; PF [O ] =(LL)PF [O] *%MOD INV2; // クラス2 } 押し上げ(O); } int型のmain(){ int型のn-RD =()、RD = Q()、T、K = 1。 ; // この数k記憶された木は使用 (ビルド1、1 、N-); 一方、(Q - ){ T = RD(); IF(Tは== 1 ){ X = RD(); Y = RD( )、 更新(1、1 、N) もし((K << = 1)> = MOD)K- = MOD。 } そう であれば(Tの== 2)重量((LL)の和[ 1 ] * k個の%のMOD)。 } フラッシュ()。 リターン 0 ; }