LOJ #3043. 「ZJOI2019」线段树 线段树+分类讨论

大大大分类讨论,思路还是非常巧妙的. 

code: 

#include <bits/stdc++.h>    
#define ll long long 
#define lson now<<1 
#define rson now<<1|1    
#define N 100008        
#define mod 998244353 
#define setIO(s) freopen(s".in","r",stdin) 
using namespace std;    
int n,m,cur;   
ll f[N<<3],g[N<<3],SUM[N<<3],qp[N],mf[N<<3],mg[N<<3];  
void markf(int now,int v) 
{
    f[now]=(ll)f[now]*qp[v]%mod;     
    SUM[now]=(ll)SUM[now]*qp[v]%mod;  
    mf[now]+=v;    
}    
void markg(int now,int v) 
{
    g[now]=(ll)g[now]*qp[v]%mod;    
    mg[now]+=v;  
}      
void pushdown(int now) 
{ 
    if(mf[now]) 
    {
        markf(lson,mf[now]); 
        markf(rson,mf[now]); 
        mf[now]=0;   
    }
    if(mg[now]) 
    {
        markg(lson,mg[now]); 
        markg(rson,mg[now]);  
        mg[now]=0;   
    }
}
void pushup(int now) 
{  
    SUM[now]=(ll)(SUM[lson]+SUM[rson]+f[now])%mod;    
}  
void build(int l,int r,int now) 
{
    f[now]=0,g[now]=1;   
    if(l==r) return;      
    int mid=(l+r)>>1;   
    build(l,mid,lson),build(mid+1,r,rson);    
}        
void update(int l,int r,int now,int L,int R) 
{     
    pushdown(now);             
    if(l>=L&&r<=R) 
    {    
        // 1 类点   
        f[now]=(ll)(f[now]+qp[cur-1])%mod;             
        markf(lson,1),markf(rson,1);                         
        pushup(now);               
        return;    
    }
    int mid=(l+r)>>1;   
    if(L<=mid&&R>mid) 
    {   
        update(l,mid,lson,L,R); 
        update(mid+1,r,rson,L,R);                 
    } 
    else if(L<=mid) 
    {
        update(l,mid,lson,L,R);      
        int p=rson;               
        pushdown(p);   
        markf(p<<1,1),markf(p<<1|1,1);     
        markg(p<<1,1),markg(p<<1|1,1);       
        f[p]=(ll)(f[p]+qp[cur-1]-g[p]+mod)%mod;     
        g[p]=(ll)(g[p]+g[p])%mod;     
        pushup(p);     
    } 
    else
    {       
 
        update(mid+1,r,rson,L,R);   
        int p=lson;                       
        pushdown(p);   
        markf(p<<1,1),markf(p<<1|1,1);     
        markg(p<<1,1),markg(p<<1|1,1);  
        f[p]=(ll)(f[p]+qp[cur-1]-g[p]+mod)%mod;     
        g[p]=(ll)(g[p]+g[p])%mod;  
        pushup(p);        
    }                 
    // 2 类点     
    // 
    g[now]=(ll)(g[now]+qp[cur-1])%mod;   
    pushup(now);          
}
int main() 
{ 
   // setIO("input"); 
    qp[0]=1;   
    for(int i=1;i<N;++i) qp[i]=(ll)qp[i-1]*2%mod;      
    scanf("%d%d",&n,&m);    
    build(1,n,1);   
    for(int i=1;i<=m;++i)
    {   
        int op,l,r;   
        scanf("%d",&op);  
        if(op==1)     
        {
            scanf("%d%d",&l,&r),++cur,update(1,n,1,l,r);   
        }
        else
        { 
            printf("%lld\n",SUM[1]);    
        }
    }
    return 0; 
}

  

posted @ 2020-04-21 23:00  EM-LGH  阅读(141)  评论(0编辑  收藏  举报