zoukankan      html  css  js  c++  java
  • 线段树模板

    void pushdown(int l, int r, int rt)
    {
        if (lazy[rt])
        {
            sum[rt << 1] += l * lazy[rt];
            sum[(rt << 1) + 1] += r * lazy[rt];
            lazy[rt << 1] += lazy[rt];
            lazy[(rt << 1) + 1] += lazy[rt];
            lazy[rt] = 0;
        }
    }
    void build(int l, int r, int rt)
    {
        if (l == r)
        {
            sum[rt] = tmp[l];
            return;
        }
        int mid = (l + r) >> 1;
        build(l, mid, rt << 1);
        build(mid + 1, r, (rt << 1) + 1);
        sum[rt] = sum[rt << 1] + sum[(rt << 1) + 1];
    }
    void update(int l, int r, int rt, int l1, int r1, int v)
    {
        if (l1 <= l && r <= r1)
        {
            sum[rt] += v * (r - l + 1);
            lazy[rt] += v;
            return;
        }
        int mid = (l + r) >> 1;
        pushdown(mid - l + 1, r - mid, rt);
        if (l1 <= mid)
            update(l, mid, rt << 1, l1, r1, v);
        if (r1 > mid)
            update(mid + 1, r, (rt << 1) + 1, l1, r1, v);
        sum[rt] = sum[rt << 1] + sum[(rt << 1) + 1];
    }
    int query(int l, int r, int rt, int l1, int r1)
    {
        if (l1 <= l && r <= r1)
            return (ll)sum[rt];
        int mid = (l + r) >> 1;
        int ret = 0;
        pushdown(mid - l + 1, r - mid, rt);
        if (l1 <= mid)
            ret += query(l, mid, rt << 1, l1, r1);
        if (r1 > mid)
            ret += query(mid + 1, r, (rt << 1) + 1, l1, r1);
        sum[rt] = sum[rt << 1] + sum[(rt << 1) + 1];
        return ret;
    }

    线段树区间加法,区间乘法,区间查询

    #include <bits/stdc++.h>
    
    #define ll long long
    #define ull unsigned long long
    #define met(a,x) memset(a,x,sizeof(a))
    #define inf 0x3f3f3f3f
    #define mp make_pair;
    
    using namespace std;
    const int maxn = 100000 + 10;
    const int mod=1e9+7;
    ll A[maxn << 1], Sum[maxn << 3], Add[maxn << 3], Mul[maxn << 3];
    ll n, s, p;
    
    void PushUp(ll rt) { Sum[rt] = (Sum[rt << 1] + Sum[rt << 1 | 1]) % p; }//上推函数
    void PushDown(ll rt, ll m)//下推函数,注意乘法优先级比加法高
    {
        if (Add[rt] || Mul[rt] != 1) {
            Sum[rt << 1] = (Sum[rt << 1] * Mul[rt] + Add[rt] * (m - (m >> 1))) % p;
            Sum[rt << 1 | 1] = (Sum[rt << 1 | 1] * Mul[rt] + Add[rt] * (m >> 1)) % p;
            Add[rt << 1] = (Add[rt << 1] * Mul[rt] + Add[rt]) % p;
            Add[rt << 1 | 1] = (Add[rt << 1 | 1] * Mul[rt] + Add[rt]) % p;
            Mul[rt << 1] = (Mul[rt << 1] * Mul[rt]) % p;
            Mul[rt << 1 | 1] = (Mul[rt << 1 | 1] * Mul[rt]) % p;
            Add[rt] = 0;
            Mul[rt] = 1;
        }
    }
    
    void Build(ll l, ll r, ll rt)//建树
    {
        Add[rt] = 0;
        Mul[rt] = 1;
        if (l == r) {
            Sum[rt] = A[l] % p;
            return;
        }
        ll m = (l + r) >> 1;
        Build(l, m, rt << 1);
        Build(m + 1, r, rt << 1 | 1);
        PushUp(rt);
    }
    
    void Update_mul(ll L, ll R, ll C, ll l, ll r, ll rt)//区间乘法运算
    {
        PushDown(rt, (r - l + 1));
        if (L <= l && r <= R) {
            Sum[rt] = Sum[rt] * C;
            Sum[rt] = Sum[rt] % p;
            Mul[rt] = Mul[rt] * C;
            Mul[rt] = Mul[rt] % p;
            return;
        }
        ll m = (l + r) >> 1;
        if (L <= m) Update_mul(L, R, C, l, m, rt << 1);
        if (R > m) Update_mul(L, R, C, m + 1, r, rt << 1 | 1);
        PushUp(rt);
    }
    
    void Update_plu(ll L, ll R, ll C, ll l, ll r, ll rt)//区间加法运算
    {
        PushDown(rt, r - l + 1);
        if (L <= l && r <= R) {
            Sum[rt] = (Sum[rt] + (r - l + 1) * C) % p;
            Add[rt] = (Add[rt] + C) % p;
            return;
        }
        ll m = (l + r) >> 1;
        if (L <= m) Update_plu(L, R, C, l, m, rt << 1);
        if (R > m) Update_plu(L, R, C, m + 1, r, rt << 1 | 1);
        PushUp(rt);
    }
    
    ll Query(ll L, ll R, ll l, ll r, ll rt)//区间查询
    {
        PushDown(rt, r - l + 1);
        if (L <= l && r <= R) {
            return Sum[rt];
        }
        ll m = (l + r) >> 1, Ans = 0;
        if (L <= m) Ans = (Ans + Query(L, R, l, m, rt << 1)) % p;
        if (R > m) Ans = (Ans + Query(L, R, m + 1, r, rt << 1 | 1)) % p;
        return Ans;
    }
    
    int main()//各种操作
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cout.tie(0);
        scanf("%lld%lld", &n, &p);
        for (int i = 1; i <= n; i++)
            scanf("%lld", &A[i]);
        Build(1, n, 1);
        scanf("%lld", &s);
        for (int i = 1; i <= s; i++) {
            ll t, x, y, k;
            scanf("%lld%lld%lld", &t, &x, &y);
            if (t == 1) {
                scanf("%lld", &k);
                Update_mul(x, y, k, 1, n, 1);
            }
            if (t == 2) {
                scanf("%lld", &k);
                Update_plu(x, y, k, 1, n, 1);
            }
            if (t == 3) {
                printf("%lld
    ", Query(x, y, 1, n, 1));
            }
        }
        return 0;
    }
  • 相关阅读:
    WebService优点和缺点小结
    MongoDB监控之一:运行状态、性能监控,分析
    MongoDB分析工具之三:db.currentOp()
    Linux NFS服务器的安装与配置
    第三方支付 转
    视频监控/存储系统设计要点
    ViewPager禁止滑动以及它与内层滑动控件水平方向上事件冲突的解决方法
    (五)unity4.6Ugui中文教程文档-------概要-UGUI Interaction Components
    ListView列表拖拽排序
    shell脚本编写汇集
  • 原文地址:https://www.cnblogs.com/nublity/p/10456611.html
Copyright © 2011-2022 走看看