• 线段树


    线段树

    P3373 【模板】线段树 2

    注:本线段树使用链表形式(指针),每个结点都是左闭右闭区间。

    操作为加或乘,最后答案模 (mod)

    打两个标记,分别为 addmul

    ll n, m, mod;
    
    struct node{
        ll L, R, add, mul, sum;
        node *lc, *rc;
        void makeadd(ll k)
        {
            sum = (sum + k * (R - L + 1)) % mod;
            add = (add + k) % mod;
        }
        void makemul(ll k)
        {
            sum = (sum * k) % mod;
            mul = (mul * k) % mod;
            add = (add * k) % mod;
        }
        void pushup()
        {
            sum = (lc->sum + rc->sum) % mod;
        }
        void pushdown()
        {
            if(mul != 1)
            {
                lc->makemul(mul);
                rc->makemul(mul);
                mul = 1;
            }
            if(add)
            {
                lc->makeadd(add);
                rc->makeadd(add);
                add = 0;
            }
        }
    };
    
    const ll N = 1e5 + 4;
    ll a[N];
    
    void Build(node *now, ll l, ll r)
    {
        now->L = l;
        now->R = r;
        now->add = 0;
        now->mul = 1;
        now->sum = 0;
        if(l < r)
        {
            ll mid = (l + r) >> 1;
            now->lc = new node;
            now->rc = new node;
            Build(now->lc, l, mid);
            Build(now->rc, mid + 1, r);
            now->pushup();
        }
        else
        {
            now->sum = a[l];
            now->lc = now->rc = NULL;
        }
    }
    
    ll check(node *now, ll l, ll r)
    {
        if(l <= now->L and now->R <= r)
            return now->sum % mod;
        now->pushdown();
        ll mid = (now->L + now->R) >> 1;
        ll ans = 0;
        if(l <= mid)
            ans = (ans + check(now->lc, l, r)) % mod;
        if(mid < r)
            ans = (ans + check(now->rc, l , r)) % mod;
        return ans % mod;
    }
    
    void add(node *now, ll l, ll r, ll k)
    {
        if(l <= now->L and now->R <= r)
            now->makeadd(k);
        else
        {
            now->pushdown();
            ll mid = (now->L + now->R) >> 1;
            if(l <= mid)
                add(now->lc, l, r, k);
            if(mid < r)
                add(now->rc, l, r, k);
            now->pushup();
        }
    }
    
    void mul(node *now, ll l, ll r, ll k)
    {
        if(l <= now->L and now->R <= r)
            now->makemul(k);
        else
        {
            now->pushdown();
            ll mid = (now->L + now->R) >> 1;
            if(l <= mid)
                mul(now->lc, l, r, k);
            if(mid < r)
                mul(now->rc, l, r, k);
            now->pushup();
        }
    }
    
    int main()
    {
        n = read(), m = read(), mod = read();
        for(int i = 1; i <= n; ++i)
            a[i] = read();
        node *root;
        root = new node;
        Build(root, 1, n);
        for(int i = 1; i <= m; ++i)
        {
            ll opt = read(), l = read(), r = read(), k;
            if(opt == 1)
            {
                k = read();
                mul(root, l, r, k);
            }
            if(opt == 2)
            {
                k = read();
                add(root, l ,r, k);
            }
            if(opt == 3)
            {
                printf("%lld
    ", check(root, l, r) % mod);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    Buffer Lock Mode and Compatibilities
    11g默认审计选项
    11.2.0.2 asmcmd lsdg show incorrect diskgroup number
    关于V$OPEN_CURSOR
    了解你所不知道的SMON功能(七):清理IND$字典基表
    PL/SQL DEPENDENCIES
    温习 Linux 命令
    温习 SQL 03
    PL/SQL 基础 ( 下 )
    HTML501 ( The.Essential.Guide )
  • 原文地址:https://www.cnblogs.com/EdisonBa/p/14948592.html
Copyright © 2020-2023  润新知