[ZJOI2019]线段树(线段树,DP)

又是神仙题。

要写博客太长了,先咕着。放个代码先。

为什么 fmul 在 linux 底下还被定义过了……能想象到我一发 CE 的绝望吗 qaq

#include<bits/stdc++.h>
using namespace std;
const int maxn=800080,mod=998244353;
#define ls o<<1
#define rs o<<1|1
#define lson ls,l,mid
#define rson rs,mid+1,r
#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define ROF(i,a,b) for(int i=(a);i>=(b);i--)
#define MEM(x,v) memset(x,v,sizeof(x))
inline int read(){
    int x=0,f=0;char ch=getchar();
    while(ch<'0' || ch>'9') f|=ch=='-',ch=getchar();
    while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
    return f?-x:x;
}
int n,m,f[maxn],g[maxn],sum[maxn],fm[maxn],gm[maxn],pt[maxn];
inline void pushup(int o){
    sum[o]=(sum[ls]+(sum[rs]+f[o])%mod)%mod;
}
inline void setf(int o,int v){
    f[o]=1ll*f[o]*v%mod;
    sum[o]=1ll*sum[o]*v%mod;
    fm[o]=1ll*fm[o]*v%mod;
}
inline void setg(int o,int v){
    g[o]=1ll*g[o]*v%mod;
    gm[o]=1ll*gm[o]*v%mod; 
}
inline void pushdown(int o){
    if(fm[o]!=1){
        setf(ls,fm[o]);
        setf(rs,fm[o]);
        fm[o]=1;
    }
    if(gm[o]!=1){
        setg(ls,gm[o]);
        setg(rs,gm[o]);
        gm[o]=1;
    }
}
void build(int o,int l,int r){
    g[o]=fm[o]=gm[o]=1;
    if(l==r) return;
    int mid=(l+r)>>1;
    build(lson);build(rson);
    pushup(o);
}
void update(int o,int l,int r,int ql,int qr,int id){
    pushdown(o);
    if(r<ql || l>qr){
        f[o]=(f[o]+(pt[id-1]-g[o]+mod)%mod)%mod;
        g[o]=2ll*g[o]%mod;
        setf(ls,2);setf(rs,2);
        setg(ls,2);setg(rs,2);
        pushup(o);
        return;
    }
    if(l>=ql && r<=qr){
        f[o]=(f[o]+pt[id-1])%mod;
        setf(ls,2);setf(rs,2);
        pushup(o);
        return;
    }
    g[o]=(g[o]+pt[id-1])%mod;
    int mid=(l+r)>>1;
    update(lson,ql,qr,id);
    update(rson,ql,qr,id);
    pushup(o);
}
int main(){
    n=read();m=read();
    pt[0]=1;
    FOR(i,1,m) pt[i]=2ll*pt[i-1]%mod;
    build(1,1,n);
    int cnt=0;
    while(m--){
        int op=read();
        if(op==1){
            int l=read(),r=read();
            update(1,1,n,l,r,++cnt);
        }
        else printf("%d\n",sum[1]);
    }
}

转载于:https://www.cnblogs.com/1000Suns/p/11558407.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值