Luo Gu P5280 / LOJ3043 / UOJ467 / BZOJ5515 [ZJOI2019] segment tree

First of all, it is easy to see the $ k $ amendment tree has $ 2 ^ k $ trees, so the violence is undoubtedly only 20pts not that I do

Therefore, we want $ 2 ^ {k} $ tree maintenance becomes a tree. Hutchison $ P_o $ $ o $ probabilities in the trees marked, the answer is $ \ sum {P_o} * 2 ^ {k} $. But because there is $ pushdown $, a node when it is accessed, as long as it and its ancestors, there is a marked, it will be marked, so we have to record $ o $ and $ o $ ancestors have at least a marked probability $ Pf_o $

Now, we influence each node changes Category:

1. The marking node

Modification occurs at half the tree, which was hit flag, there is a probability of $ 1 $ mark, the probability of the other half unchanged, $ P_o = \ frac {P_o + 1} {2} $, Similarly, $ Pf_o = \ frac {Pf_o + 1} {2} $.

2. is $ modify $ visit, but did not hit the mark of the node

Modification occurs in half of the tree, its ancestors and mark all been pushed down, the other half unchanged. Therefore $ P_o = \ frac {P_o} {2}, Pf_o = \ frac {Pf_o} {2} $.

3. is $ pushdown $ visit, but not modify $ $ node access

$ Pf_o $ thereof unchanged (between it and the push ancestor not push all the same), but as long as the tag ancestors, since it will take $ $ pushdown mark, so $ P_o = \ frac {P_o + Pf_o} {2 } $.

4. marking the node subtree

$ P_o $ undoubtedly thereof unchanged, but after modification, whose ancestors must be marked, so $ Pf_o = \ frac {Pf_o + 1} {2} $.

This class of nodes may have $ O (n) $ th, so we can not directly be changed, but can be modified in fact found by the $ \ frac {1} {2 } plus $ $ \ frac {1} {2 } $, so like the tree line 2 as lazy maintenance mark on it

#include <cstdio> 
typedef Long  Long LL;
 const  int MOD = 998 244 353 ;
 const  int INV2 = 499 122 177 ;   // inverse element 2 is frequently used, to keep down 
const  int N = 100050, China ;
 char rB [ . 1 << 21 is ], * S, T *, wB [ . 1 << 21 is ];
 int WP = - . 1 ; 
inline char GC () { return S && == T (T = (S = rB) + fread (rB, . 1 , . 1 << 21 is , ? stdin), S == T) EOF: * S ++;}
inline void flush(){fwrite(wB,1,wp+1,stdout);wp=-1;}
inline void pc(char c){if(wp+1==(1<<21))flush();wB[++wp]=c;}
inline int rd(){
    char c=gc();
    while(c<48||c>57)c=gc();
    int x=c&15;
    for(c=gc();c>=48&&c<=57;c=gc())x=(x<<3)+(x<<1)+(c&15);
    return x;
}
short buf[15];
inline void wt(int x){
    short l=-1;
    while(x>9){
        buf[++l]=x%10;
        x/=10;
    }
    pc(x|48);
    while(l>=0)pc(buf[l--]|48);
    pc('\n');
} 
Int P [N << 2 ], PF [N << 2 ], MuLV [N << 2 ], ADDV [N << 2 ], SUM [<< N . 3 ], X, Y;   // this written in the leaf nodes will pushup, so to open a large sum to extra 
void Build ( 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 ; 
        Build (LC, L, M); Build (RC, M + . 1 , R & lt); 
    } 
} 
inline void a pushup (int o){
    int lc=o<<1,rc=lc|1;
    sum[o]=((ll)p[o]+sum[lc]+sum[rc])%mod;
}
inline void pushdown(int o){
    int lc=o<<1,rc=lc|1;
    if(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;
    }
    if(addv[o]){
        if((addv[lc]+=addv[o])>=mod)addv[lc]-=mod;if((pf[lc]+=addv[o])>=mod)pf[lc]-=mod;
        if((addv[rc]+=addv[o])>=mod)addv[rc]-=mod;if((pf[rc]+=addv[o])>=mod)pf[rc]-=mod;
        addv[o]=0;
    }
}
void update(int o,int L,int R){
    if(x<=L&&y>=R){  //第1类
        p[o]=((ll)p[o]*inv2+inv2)%mod;
        pf[o]=((ll)pf[o]*inv2+inv2)%mod;
        MuLV [O]= (LL) MuLV [O] *% INV2 MOD; 
        ADDV [O] = ((LL) ADDV [O] + * INV2 INV2)% MOD;   // play lazy marked as modified Class 4 
    } the else {
         int LC << O = . 1 , LC RC = | . 1 , M = L + R & lt >> . 1 ; 
        pushdown (O); 
        IF (X <= M) Update (LC, L, M);
         the else { 
            P [LC] = ( (LL) P [LC] * INV2 + (LL) PF [LC] * INV2)% MOD; 
            a pushup (LC); 
        }   // class. 3 
        IF (Y> M) Update (RC, M + . 1 , R & lt);
         the else { 
            P [RC]= ((LL) P [RC] * INV2 + (LL) PF [RC] * INV2)% MOD; 
            a pushup (RC); 
        } 
        P [O] = (LL) P [O] * INV2% MOD; PF [O ] = (LL) PF [O] *% MOD INV2;   // class 2 
    } 
    a pushup (O); 
} 
int main () {
     int n-RD = (), RD = Q (), T, K = . 1 ;   // use this number k stored trees 
    Build ( . 1 , . 1 , n-);
     the while (q - ) { 
        T = RD ();
         IF (T == . 1 ) { 
            X = RD (); Y = RD ( ); 
            Update ( . 1 ,1,n);
            if((k<<=1)>=mod)k-=mod;
        }else if(t==2)wt((ll)sum[1]*k%mod);
    }
    flush();
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/sunshine-chen/p/11258796.html