6:
      LAZY 线段树有乘法的更新
   #include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int maxn = 101000;
long long value[maxn], mod;
struct SegNode {
    int left, right;
    long long sum, add, mul;
    int mid() {
        return (left + right) >> 1;
    }
    int size() {
        return right - left + 1;
    }
};
struct SegmentTree {
    SegNode tree[maxn*5];
    void pushUp(int idx) {
        tree[idx].sum = (tree[idx<<1].sum + tree[idx<<1|1].sum) % mod;
    }
    void pushDown(int idx) {
        tree[idx<<1].add = (tree[idx].mul % mod * tree[idx<<1].add % mod + tree[idx].add) % mod;
        tree[idx<<1|1].add = (tree[idx].mul % mod * tree[idx<<1|1].add % mod + tree[idx].add) % mod;
        tree[idx<<1].mul = tree[idx<<1].mul % mod * tree[idx].mul % mod;
        tree[idx<<1|1].mul = tree[idx<<1|1].mul % mod * tree[idx].mul % mod;
        tree[idx<<1].sum = (tree[idx<<1].sum % mod * tree[idx].mul % mod
            + tree[idx<<1].size() * tree[idx].add % mod) % mod;
        tree[idx<<1|1].sum = (tree[idx<<1|1].sum % mod * tree[idx].mul % mod
            + tree[idx<<1|1].size() * tree[idx].add % mod) % mod;
        tree[idx].add = 0;
        tree[idx].mul = 1;
    }
    void build(int left, int right, int idx) {
        tree[idx].left = left;
        tree[idx].right = right;
        tree[idx].sum = 0;
        tree[idx].mul = 1;
        tree[idx].add = 0;
        if (left == right) {
            tree[idx].sum = value[left] % mod;
            return ;
        }
        int mid = tree[idx].mid();
        build(left, mid, idx<<1);
        build(mid+1, right, idx<<1|1);
        pushUp(idx);
    }
    void update(int left, int right, int idx, int opt, long long val) {
        if (tree[idx].left == left && tree[idx].right == right) {
            if (opt == 1) {
                tree[idx].add = (tree[idx].add + val) % mod;
                tree[idx].sum = (tree[idx].sum + tree[idx].size() % mod * val) % mod;
            } else {
                tree[idx].add = tree[idx].add % mod * val % mod;
                tree[idx].mul = tree[idx].mul % mod * val % mod;
                tree[idx].sum = tree[idx].sum % mod * val % mod;
            }
            return ;
        }
        pushDown(idx);
        int mid = tree[idx].mid();
        if (right <= mid)
            update(left, right, idx<<1, opt, val);
        else if (left > mid)
            update(left, right, idx<<1|1, opt, val);
        else {
            update(left, mid, idx<<1, opt, val);
            update(mid+1, right, idx<<1|1, opt, val);
        }
        pushUp(idx);
    }
    long long query(int left, int right, int idx) {
        if (tree[idx].left == left && tree[idx].right == right) {
            return tree[idx].sum % mod;
        }
        pushDown(idx);
        int mid = tree[idx].mid();
        if (right <= mid)
            return query(left, right, idx<<1);
        else if (left > mid)
            return query(left, right, idx<<1|1);
        else {
            return (query(left, mid, idx<<1) % mod + query(mid+1, right, idx<<1|1));
        }
    }
};
SegmentTree tree;
int n, m;
void init() {
    scanf("%d %lld", &n, &mod);
    for (int i = 1; i <= n; i++)
        scanf("%lld", &value[i]);
    tree.build(1, n, 1);
}

BZOJ 1798:的更多相关文章

  1. BZOJ 1798 题解

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

  2. bzoj 1798 [Ahoi2009]Seq 维护序列seq

    原题链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1798 线段树区间更新: 1. 区间同同时加上一个数 2. 区间同时乘以一个数 #inclu ...

  3. bzoj 1798 [Ahoi2009]Seq 维护序列seq(线段树+传标)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1798 [题意] 给定一个序列,要求提供区间乘/加,以及区间求和的操作 [思路] 线段树 ...

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

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

  5. bzoj 1798: [Ahoi2009]Seq 维护序列seq (线段树 ,多重标记下放)

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

  6. bzoj 1798 线段树

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

  7. bzoj 1798: [Ahoi2009]Seq 维护序列seq 线段树 区间乘法区间加法 区间求和

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeO ...

  8. bzoj 1798 双标记区间修改线段树

    #include<bits/stdc++.h> using namespace std; #define MAXN 100000 #define M ((L+R)>>1) #d ...

  9. bzoj 1798 维护序列seq

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1798 题解: 高级一点的线段树,加上了区间乘法运算,则需要增加一个数组mulv记录乘的因数 ...

  10. 值得一做》关于双标记线段树两三事BZOJ 1798 (NORMAL-)

    这是一道双标记线段树的题,很让人很好的预习/学习/复习线段树,我不知道它能让别人学习什么,反正让我对线段树的了解更加深刻. 题目没什么好讲的,程序也没什么好讲的,所以也没有什么题解,但是值得一做 给出 ...

随机推荐

  1. codevs 5438 zbd之难题(水题日常)

     时间限制: 1 s  空间限制: 1000 KB  题目等级 : 白银 Silver 题目描述 Description zbd想要一个计算器,请你编一个计算器. 输入描述 Input Descrip ...

  2. oracle插入中文乱码

    执行sql: select  userenv('language')     from dual;  --  AMERICAN_AMERICA.ZHS16GBK select * from v$nls ...

  3. expand - 把 tab 符转换为空格符

    总览 (SYNOPSIS) ../src/expand [OPTION]... [FILE]... 描述 (DESCRIPTION) 把 各文件 FILE 中的 tab 符 转换为 空格符, 然后 写 ...

  4. this.$refs.tabs.activeKey ref就是vue里面的id

    this.$refs.tabs.activeKey ref就是vue里面的id

  5. Ubuntu修改时区和时间

    1.查看当前时区 date -R 返回显示是 +0000 2.修改时区 tzselect 然后提示选择时区,按顺序选4.9.1,然后确认选1 3.更新本地时区 sudo cp /usr/share/z ...

  6. No-2.常用 Linux 命令的基本使用

    常用 Linux 命令的基本使用 01. 学习 Linux 终端命令的原因 Linux 刚面世时并没有图形界面,所有的操作全靠命令完成,如 磁盘操作.文件存取.目录操作.进程管理.文件权限 设定等 在 ...

  7. ssh和sshd服务

    1.1 对称加密和非对称加密 对称加密:加密和解密使用一样的算法,只要解密时提供与加密时一致的密码就可以完成解密.例如QQ登录密码,银行卡密码,只要保证密码正确就可以. 非对称加密:通过公钥(publ ...

  8. CSS3---关于背景

    1.background-origin:设置元素背景图片的原始起始位置. background-origin : border-box | padding-box | content-box;    ...

  9. idea 神键

    http://blog.csdn.net/dc_726/article/details/42784275 idea 中几个十分酸爽的快捷键.

  10. Leetcode 260.只出现一次的数字III

    只出现一次的数字III 给定一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次. 找出只出现一次的那两个元素. 示例 : 输入: [1,2,1,3,2,5] 输出: [3,5 ...