线段树维护两个标记。

*0的操作在实质上没有任何影响。

#include <cstdio>
#include <cctype>

#define rep(i,a,b) for (int i=(a);i<=(b);i++)

#define LL long long

#define lc (x<<1)
#define rc (x<<1|1)
#define siz(x) (tr[x].r-tr[x].l+1)

const int N=131072;
const int S=262144;

int n,p,m,a[N];
struct Tree {
    int l,r;
    int a,b;        //tag(a,b): ax+b
    int sum;
    Tree(int _l=0,int _r=0) {
        l=_l,r=_r;
        a=1,b=0;
        sum=0;
    }
}tr[S];

int rd(void) {
    int x=0,f=1; char c=getchar();
    while (!isdigit(c)) {
        if (c=='-') f=-1;
        c=getchar();
    }
    while (isdigit(c)) {
        x=x*10+c-'0';
        c=getchar();
    }
    return x*f;
}

void Pushup(int x) {
    tr[x].sum=(tr[lc].sum+tr[rc].sum)%p;
}

void Clear(int x) {
    int a=tr[x].a,b=tr[x].b; if (a==1&&!b) return; tr[x].a=1,tr[x].b=0;
    tr[lc].sum=((LL)a*tr[lc].sum+(LL)b*siz(lc))%p; tr[lc].a=(LL)a*tr[lc].a%p; tr[lc].b=((LL)a*tr[lc].b+b)%p;
    tr[rc].sum=((LL)a*tr[rc].sum+(LL)b*siz(rc))%p; tr[rc].a=(LL)a*tr[rc].a%p; tr[rc].b=((LL)a*tr[rc].b+b)%p;
}

void Build(int x,int l,int r) {
    tr[x]=Tree(l,r);
    if (l!=r) {
        int mid=(l+r)>>1;
        Build(lc,l,mid);
        Build(rc,mid+1,r);
        Pushup(x);
    }
    else tr[x].sum=a[l];
}

void Modify(int x,int l,int r,int a,int b) {
    if (l<=tr[x].l&&tr[x].r<=r) {
        tr[x].sum=((LL)a*tr[x].sum+(LL)b*siz(x))%p;
        tr[x].a=(LL)a*tr[x].a%p;
        tr[x].b=((LL)a*tr[x].b+b)%p;
        return;
    }
    Clear(x);
    int mid=(tr[x].l+tr[x].r)>>1;
    if (l<=mid)
        Modify(lc,l,r,a,b);
    if (mid<r)
        Modify(rc,l,r,a,b);
    Pushup(x);
}

int Query(int x,int l,int r) {
    if (l<=tr[x].l&&tr[x].r<=r) return tr[x].sum;
    Clear(x);
    int sum=0; int mid=(tr[x].l+tr[x].r)>>1;
    if (l<=mid) {
        int t=Query(lc,l,r);
        sum=(sum+t)%p;
    }
    if (mid<r) {
        int t=Query(rc,l,r);
        sum=(sum+t)%p;
    }
    return sum;
}

int main(void) {
    #ifndef ONLINE_JUDGE
    freopen("sd.in","r",stdin);
    freopen("sd.out","w",stdout);
    #endif

    n=rd(),p=rd();
    rep(i,1,n) a[i]=rd();
    Build(1,1,n);

    m=rd();
    rep(i,1,m) {
        int kd=rd(); int x,y,z;
        switch (kd) {
            case 1:
                x=rd(),y=rd(),z=rd();
                Modify(1,x,y,z,0);
                break;
            case 2:
                x=rd(),y=rd(),z=rd();
                Modify(1,x,y,1,z);
                break;
            case 3:
                x=rd(),y=rd();
                int res=Query(1,x,y);
                printf("%d\n",res);
                break;
        }
    }

    return 0;
}

【bzoj1798】维护序列的更多相关文章

  1. BZOJ1798 维护序列seq

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 8058  Solved: 2964[Submit ...

  2. 【双标记线段树】bzoj1798维护序列seq

    一.题目 描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,-,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列 ...

  3. bzoj1798 维护序列

    Description 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2 ...

  4. p2023&bzoj1798 维护序列

    传送门(洛谷) 传送门(bzoj) 题目 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中的一段数全 ...

  5. bzoj1798维护序列

    题目链接 暴力数据结构之线段树$qwq$ 裸题直接敲板子 忘了啥时候写的了$qwq$ 直接上代码吧 /************************************************* ...

  6. BZOJ-1798 维护序列

    线段树.支持区间加.区间乘.区间查询和. 标记下移还有取模要注意. var n,p,q,i,s,t:longint; a:int64; num,n1,n2,n3:array[0..500000] of ...

  7. BZOJ1798: [Ahoi2009]Seq 维护序列seq[线段树]

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 5504  Solved: 1937[Submit ...

  8. [AHOI 2009] 维护序列(线段树模板题)

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MB Description 老师交给小可可一个维护数列的任务,现在小 ...

  9. bzoj 维护序列seq(双标记线段树)

    Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 4184  Solved: 1518[Submit][Status][Discus ...

  10. BZOJ 1798: [Ahoi2009]Seq 维护序列seq( 线段树 )

    线段树.. 打个 mul , add 的标记就好了.. 这个速度好像还挺快的...( 相比我其他代码 = = ) 好像是#35.. ---------------------------------- ...

随机推荐

  1. JS之对象

    每个对象的属性有两种,每种属性有4中特征描述符 1.数据属性 1.1 [[configurable]]:表示不能通过delete删除属性,不能修改属性的特性,不能将数据属性改为访问器属性,默认值fal ...

  2. linq小笔记;

    1.比较LINQ to Entities的AsQueryable和AsEnumerable方法 C#程序: 复制内容到剪贴板程序代码 using (testContext context = new ...

  3. Android应用程序窗口(Activity)与WindowManagerService服务的连接过程分析

    在前两文中,我们分析了Activity组件的窗口对象和视图对象的创建过程.Activity组件在其窗口对象和视图对象创建完成之后,就会请求与WindowManagerService建立一个连接,即请求 ...

  4. 关于HTML中标签<a>使用js的注意事项

    以下两点都不可取: 1.<a href="#" onClick="popUp('http://www.baidu.com');return false;" ...

  5. 九步轻松实现SVN创建管理项目

    本节向大家描述一下在Windows上使用Subversion中如何使用SVN创建管理项目,在这里和大家分享一下,欢迎大家一起来学习在 使用SVN创建管理项目的方法.首先看一下SVN介绍. Subver ...

  6. MySql 首记

    1.连接数据: 格式是:  -P 端口号  -h  mysql主机名\ip -u root (用户)  -p 2.显示数据库: show databases; 3.选择数据库: use databas ...

  7. 批处理命令——for

    [1]for命令简介 先把for循环与for命令类比一下,这样学习理解快. for 循环语句,一般格式如下: for (表达式1;表达式2;表达式3) { 循环体; } 1. 表达式1 一般为初始状态 ...

  8. Android实现归属地查询功能

    实现归属地查询大体有两种方法可以实现,一种是通过归属地API进行查询,另一种是查询本地数据库.两种方法各有优劣,最好结合起来使用,我本次采用的是查询数据库的方法.首先需要从网上下载归属地数据库call ...

  9. [转]tomcat中的session管理

    转载地址:http://blog.csdn.net/iloveqing/article/details/1544958 当一个sesson开始时,Servlet容器会创建一个HttpSession对象 ...

  10. miniUI datagrid 获取序号

    获取每一个row以后,其中的row._index字段和页面上显示的序号虽然看起来一样, 但是实际上不是同一个东西,如果用客户端排序模式,排序后,row._index和页面显示的序号就对不上了. 正确的 ...