zoukankan      html  css  js  c++  java
  • 线段树 P4588 【线段树用法】

    题目

    https://www.luogu.com.cn/problem/P4588

    思路

    简单来说就是使用线段树来保存操作步骤,因为如果直接计算的话long long会溢出,所以建立一个【1,Q】的线段树,使用线段树的叶子节点来表示权值,非叶子节点表示操作过程

    开始的时候线段树的叶子节点初始化为1,而非叶子节点c[k] = c[k << 1] * c[k << 1 | 1] % mod;也为1。

    当开始进行操作的时候,如果是

    操作1,m:就把对应序号(第几次操作)的线段树的叶子节点更新为m,之后递归更新父节点

    操作2,a:就把对应m【a】的线段树的叶子节点更新为1,之后递归更新父节点

    也可以这么理解:线段树是按照时间顺序建立的,这样就可以在执行除法之前将数字改为1,乘1 相当于后面的除

    代码

    #include<iostream>
    #include<cstdio>
    using namespace std;
    typedef long long ll;
    #define MAX 100001
    ll c[MAX<<2], m[100001];
    int t, q, mod,a,b;
    void build(int l, int r,int k)
    {
        if (l == r)
        {
            c[k] = 1;
        }
        else
        {
            int  m = (l + r) >> 1;
            build(l, m, k << 1);
            build(m + 1, r, k << 1 | 1);
            c[k] = c[k << 1] * c[k << 1 | 1] % mod;
        }
    }
    void update(int index,ll v,int l, int r, int k)
    {
        if (l == r)
        {
            c[k] = v;
        }
        else
        {
            int m = (l + r) >> 1;
            if (index <= m)
                update(index, v, l, m, k << 1);
            else
                update(index, v, m + 1, r, k << 1 | 1);
            c[k] = c[k << 1] * c[k << 1 | 1] % mod;
        }
    
    }
    int main()
    {
        scanf("%d", &t);
        while (t--)
        {
            scanf("%d %d", &q, &mod);
            build(1, q, 1);
            for (int i = 1; i <= q; i++)
            {
                scanf("%d %lld", &a, &m[i]);
                if (a == 1)update(i, m[i], 1, q, 1);
                else update(m[i], 1, 1, q, 1);
                printf("%lld
    ", c[1]);
            }
        }
    
    }
  • 相关阅读:
    jQuery 选择器
    jQuery 语法
    jQuery 简介
    JSON 使用
    JSON 语法
    Android——Activity跳转
    Activity
    Activity2.java
    Android——Activity练习
    Andriod——手机尺寸相关的概念 +尺寸单位+关于颜色
  • 原文地址:https://www.cnblogs.com/Jason66661010/p/12823321.html
Copyright © 2011-2022 走看看