zoukankan      html  css  js  c++  java
  • 【bzoj1798】[Ahoi2009]Seq 维护序列seq 线段树

    题目描述

    老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成。 有长为N的数列,不妨设为a1,a2,…,aN 。有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一段数全部加一个值; (3)询问数列中的一段数的和,由于答案可能很大,你只需输出这个数模P的值。

    输入

    第一行两个整数N和P(1≤P≤1000000000)。第二行含有N个非负整数,从左到右依次为a1,a2,…,aN, (0≤ai≤1000000000,1≤i≤N)。第三行有一个整数M,表示操作总数。从第四行开始每行描述一个操作,输入的操作有以下三种形式: 操作1:“1 t g c”(不含双引号)。表示把所有满足t≤i≤g的ai改为ai×c (1≤t≤g≤N,0≤c≤1000000000)。 操作2:“2 t g c”(不含双引号)。表示把所有满足t≤i≤g的ai改为ai+c (1≤t≤g≤N,0≤c≤1000000000)。 操作3:“3 t g”(不含双引号)。询问所有满足t≤i≤g的ai的和模P的值 (1≤t≤g≤N)。 同一行相邻两数之间用一个空格隔开,每行开头和末尾没有多余空格。

    输出

    对每个操作3,按照它在输入中出现的顺序,依次输出一行一个整数表示询问结果。

    样例输入

    7 43
    1 2 3 4 5 6 7
    5
    1 2 5 5
    3 2 4
    2 3 7 9
    3 1 3
    3 4 7

    样例输出

    2
    35


    题解

    线段树裸题

    唯一要注意的是两种标记的处理:pushdown中始终是先乘后加,而在乘的时候把原有的加标记也乘上这个数。原理应该不难想。

    #include <cstdio>
    #include <cstring>
    #define lson l , mid , x << 1
    #define rson mid + 1 , r , x << 1 | 1
    typedef long long lint;
    lint mod , sum[400010] , add[400010] , mul[400010];
    void pushup(int x)
    {
        sum[x] = (sum[x << 1] + sum[x << 1 | 1]) % mod;
    }
    void pushdown(int l , int r , int x)
    {
        int mid = (l + r) >> 1;
        if(mul[x] != 1)
        {
            sum[x << 1] = sum[x << 1] * mul[x] % mod;
            sum[x << 1 | 1] = sum[x << 1 | 1] * mul[x] % mod;
            add[x << 1] = add[x << 1] * mul[x] % mod;
            add[x << 1 | 1] = add[x << 1 | 1] * mul[x] % mod;
            mul[x << 1] = mul[x << 1] * mul[x] % mod;
            mul[x << 1 | 1] = mul[x << 1 | 1] * mul[x] % mod;
            mul[x] = 1;
        }
        if(add[x])
        {
            sum[x << 1] = (sum[x << 1] + add[x] * (mid - l + 1)) % mod;
            sum[x << 1 | 1] = (sum[x << 1 | 1] + add[x] * (r - mid)) % mod;
            add[x << 1] = (add[x << 1] + add[x]) % mod;
            add[x << 1 | 1] = (add[x << 1 | 1] + add[x]) % mod;
            add[x] = 0;
        }
    }
    void build(int l , int r , int x)
    {
        mul[x] = 1;
        if(l == r)
        {
            scanf("%lld" , &sum[x]);
            sum[x] %= mod;
            return;
        }
        int mid = (l + r) >> 1;
        build(lson);
        build(rson);
        pushup(x);
    }
    void updatemul(int b , int e , lint m , int l , int r , int x)
    {
        if(b <= l && r <= e)
        {
            sum[x] = sum[x] * m % mod;
            add[x] = add[x] * m % mod;
            mul[x] = mul[x] * m % mod;
            return;
        }
        pushdown(l , r , x);
        int mid = (l + r) >> 1;
        if(b <= mid) updatemul(b , e , m , lson);
        if(e > mid) updatemul(b , e , m , rson);
        pushup(x);
    }
    void updateadd(int b , int e , lint a , int l , int r , int x)
    {
        if(b <= l && r <= e)
        {
            sum[x] = (sum[x] + a * (r - l + 1)) % mod;
            add[x] = (add[x] + a) % mod;
            return;
        }
        pushdown(l , r , x);
        int mid = (l + r) >> 1;
        if(b <= mid) updateadd(b , e , a , lson);
        if(e > mid) updateadd(b , e , a , rson);
        pushup(x);
    }
    lint query(int b , int e , int l , int r , int x)
    {
        if(b <= l && r <= e)
            return sum[x];
        pushdown(l , r , x);
        int mid = (l + r) >> 1;
        lint ans = 0;
        if(b <= mid) ans = (ans + query(b , e , lson)) % mod;
        if(e > mid) ans = (ans + query(b , e , rson)) % mod;
        return ans;
    }
    int main()
    {
        int n , m , p , l , r;
        lint k;
        scanf("%d%lld" , &n , &mod);
        build(1 , n , 1);
        scanf("%d" , &m);
        while(m -- )
        {
            scanf("%d%d%d" , &p , &l , &r);
            switch(p)
            {
                case 1: scanf("%lld" , &k); updatemul(l , r , k , 1 , n , 1); break;
                case 2: scanf("%lld" , &k); updateadd(l , r , k , 1 , n , 1); break;
                default: printf("%lld
    " , query(l , r , 1 , n , 1));
            }
        }
        return 0;
    }
  • 相关阅读:
    关于本人对javascript闭包的理解
    关于闭包内存泄露的处理方法
    javascript超时调用、间歇调用
    浏览器加载和渲染html的顺序
    CSS hack
    JS在操作IE与FF的一些区别
    javascript对select option操作
    jsp端使用ApplicationContext
    人生的35个经典好习惯
    2008个人总结
  • 原文地址:https://www.cnblogs.com/GXZlegend/p/6406433.html
Copyright © 2011-2022 走看看