BZOJ 1798 [Ahoi2009]Seq 维护序列seq 线段树

BZOJ 1798 [Ahoi2009]Seq 维护序列seq 线段树

大家好,又见面了,我是全栈君。

题意:链接

方法:线段树

解析:

俩标记sb题

更新乘的时候更新加

完了

代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define N 100010
using namespace std;
typedef long long ll;
ll mul[N<<2],sum[N<<2],add[N<<2];
ll n,mod;
int q;
void pushup(int rt)
{
    sum[rt]=(sum[rt<<1]+sum[rt<<1|1])%mod;
}
void pushdown(int rt,ll m)
{
    if(mul[rt]!=1||add[rt]!=0)
    {
        mul[rt<<1]=(mul[rt<<1]*mul[rt])%mod;
        mul[rt<<1|1]=(mul[rt<<1|1]*mul[rt])%mod;
        add[rt<<1]=(mul[rt]*add[rt<<1]+add[rt])%mod;
        add[rt<<1|1]=(mul[rt]*add[rt<<1|1]+add[rt])%mod;
        sum[rt<<1]=(sum[rt<<1]*mul[rt]+(m-(m>>1))*add[rt])%mod;
        sum[rt<<1|1]=(sum[rt<<1|1]*mul[rt]+(m>>1)*add[rt])%mod;
        mul[rt]=1,add[rt]=0;
    }
}
void build(int l,int r,int rt)
{
    mul[rt]=1,sum[rt]=0;
    if(l==r)
    {
        scanf("%I64d",&sum[rt]);
        return;
    }
    int mid=(l+r)>>1;
    build(lson),build(rson);
    pushup(rt);
}
void update_mul(int L,int R,int l,int r,int rt,ll c)
{
    if(L<=l&&r<=R)
    {
        mul[rt]=(mul[rt]*c)%mod;
        add[rt]=(add[rt]*c)%mod;
        sum[rt]=(sum[rt]*c)%mod;
        return;
    }
    pushdown(rt,r-l+1);
    int mid=(l+r)>>1;
    if(L<=mid)update_mul(L,R,lson,c);
    if(R>mid) update_mul(L,R,rson,c);
    pushup(rt);
}
void update_add(int L,int R,int l,int r,int rt,ll c)
{
    if(L<=l&&r<=R)
    {
        add[rt]=(add[rt]+c)%mod;
        sum[rt]=(sum[rt]+(r-l+1)*c)%mod;
        return;
    }
    pushdown(rt,r-l+1);
    int mid=(l+r)>>1;
    if(L<=mid)update_add(L,R,lson,c);
    if(R>mid)update_add(L,R,rson,c);
    pushup(rt);
}
ll query(int L,int R,int l,int r,int rt)
{
    ll ret=0;
    if(L<=l&&r<=R)
    {
        return sum[rt];
    }
    pushdown(rt,r-l+1);
    int mid=(l+r)>>1;
    if(L<=mid)ret=(ret+query(L,R,lson))%mod;
    if(R>mid)ret=(ret+query(L,R,rson))%mod;
    pushup(rt);
    return ret;
}
int main()
{
    scanf("%lld%lld",&n,&mod);
    build(1,n,1);
    scanf("%d",&q);
    while(q--)
    {
        int opt;scanf("%d",&opt);
        int x,y;scanf("%d%d",&x,&y);
        ll z;
        switch(opt)
        {
            case 1:scanf("%lld",&z);update_mul(x,y,1,n,1,z);break;
            case 2:scanf("%lld",&z);update_add(x,y,1,n,1,z);break;
            case 3:printf("%lld\n",query(x,y,1,n,1));break;
        }
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/115363.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • jedis 集群_iis配置api

    jedis 集群_iis配置api项目中会常用到redis,但JedisCluster的使用api还是比较多,经常可能会记不太清楚,故这里将大部分JedisCluster的api贴出来,供大家参考。一、redis在工作是一个常见的工具,这里对redis和springboot形成集群的使用。(1)引入对应redis集群所需要maven文件<dependency><groupId&g…

    2022年10月14日
    2
  • git查看本地分支对应的远程分支_git 查看远程分支地址

    git查看本地分支对应的远程分支_git 查看远程分支地址在项目目录下右键GitBashHere输入如下命令:$gitbranch*master效果如下:本地只有一个master分支

    2022年8月22日
    8
  • 网卡bonding模式 – bond0、1、4配置

    网卡bonding简介网卡绑定就是把多张物理网卡通过软件虚拟成一个虚拟的网卡,配置完毕后,所有的物理网卡的ip和mac将会变成相同的。多网卡同时工作可以提高网络速度,还可以实现网卡的负载均衡、冗余。bonding模式1    round-robin(mode=0)轮转策略,轮流在每一个slave网卡上发送数据包,提供负载均衡和容错能力。     

    2022年4月7日
    39
  • Linux下快速设定ip bond

    在计算机网路普及的初期,很多OS系统都使用的为单网卡方式,即一个网卡使用一个IP地址。随着网络要求的不断提高,我们可以对多个网卡进行绑定聚合当一个逻辑网络接口来使用,从而大幅提升服务器的网络吞吐(I/

    2021年12月26日
    68
  • zigbee 协议栈睡眠用法[通俗易懂]

    zigbee 协议栈睡眠用法[通俗易懂]大家都知道2430有3种睡眠模式,pm2模式比较省功耗而且可以被定时唤醒;pm3模式最省电但是只能被外部中断唤醒。开启睡眠功能很简单:首先确认/TexasInstruments/ZStack-1.4.3-1.2.1/Projects/zstack/Tools/CC2430DB目录下的f8wConfig.cfg文件中DRFD_RCVC_ALWAYS_ON定义为FALSE;然后在IAR的

    2022年5月22日
    34
  • kaptcha验证码[通俗易懂]

    kaptcha验证码[通俗易懂]kaptcha是一个非常实用的验证码生成工具。有了它,你可以生成各种样式的验证码,因为它是可配置的。kaptcha工作的原理是调用com.google.code.kaptcha.servlet.KaptchaServlet,生成一个图片。同时将生成的验证码字符串放到HttpSession中。使用kaptcha可以方便的配置: 验证码的字体验证码字体的大小验证码字体的字

    2022年6月18日
    27

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号