zoukankan      html  css  js  c++  java
  • TJOI2018 数学计算 题解

    题目

    小豆现在有一个数 (x) ,初始值为 (1) 。 小豆有 (Q) 次操作,操作有两种类型:

    1. (m)(x=x×m),输出 (xmod M)

    2. (pos)(x=x/)(pos) 次操作所乘的数(保证第 (pos) 次操作一定为类型 (1),对于每一个类型 (1) 的操作至多会被除一次),输出 (xmod M)

    输入格式

    一共有 (t) 组输入。
    对于每一组输入,第一行是两个数字 (Q,M)
    接下来 (Q) 行,每一行为操作类型 (op) ,操作编号或所乘的数字 (m) (保证所有的输入都是合法的)。

    输出格式

    对于每一个操作,输出一行,包含操作执行后的 (xmod M)的值

    样例输入

    1
    10 1000000000
    1 2
    2 1
    1 2
    1 10
    2 3
    2 4
    1 6
    1 7
    1 12
    2 7
    

    样例输出

    2
    1
    2
    20
    10
    1
    6
    42
    504
    84
    

    数据范围

    对于 (20\%) 的数据, (1≤Q≤500)
    对于 (100\%) 的数据, (1≤Q≤10^5,t≤5,M≤10^9)

    题解

    使用线段树存储区间积, 每次除改回来一个点

    代码

    #include <bits/stdc++.h>
    using namespace std;
    #define int long long
    const int N = 1e5 + 10;
    int n, p;
    struct Tree {
        struct Data { int L, r, mul; } data[N << 2];
        void build(int v, int L, int r) {
            data[v] = (Data){L, r, 1};
            if (L == r) return;
            int mid = L + r >> 1;
            build(v << 1, L, mid), build(v << 1 | 1, mid + 1, r);
        }
        void update(int v, int A, int b, int k) {
            if (data[v].L > b || data[v].r < A) return;
            if (A <= data[v].L && data[v].r <= b)
                return data[v].mul = 1ll * data[v].mul * k % p, void();
            update(v << 1, A, b, k), update(v << 1 | 1, A, b, k);
        }
        void query(int v, int k) {
            k = 1ll * k * data[v].mul % p;
            if (data[v].L == data[v].r) return printf("%d
    ", k), void();
            query(v << 1, k), query(v << 1 | 1, k);
        }
    } tree;
    struct OP { int pos, m; } a[N];
    signed main() {
        int T;
        scanf("%lld", &T);
        while (T--) {
            scanf("%lld%lld", &n, &p);
            tree.build(1, 1, n);
            for (int i = 1; i <= n; i++) {
                int op, x;
                scanf("%lld%lld", &op, &x);
                if (op == 1) a[i] = (OP){i, x};
                else {
                    tree.update(1, a[x].pos, i - 1, a[x].m);
                    a[x] = (OP){0, 0};
                }
            }
            for (int i = 1; i <= n; i++)
                if (a[i].pos) tree.update(1, a[i].pos, n, a[i].m);
            for (int i = 1; i <= n; i++) a[i] = (OP){0, 0};
            tree.query(1, 1);
        }
        return 0;
    }
    
  • 相关阅读:
    arcgis对谷歌遥感影像拼接
    animation动画
    通过$ref设置样式
    Element drawer添加 滚动条 无法上下滚动
    ECharts 点击事件的 param参数
    解析后台参数
    .NET Core中具有多个实现的依赖注入实现
    玩转Firefox侧栏
    实用AutoHotkey功能展示
    利用7z实现一键解压
  • 原文地址:https://www.cnblogs.com/youxam/p/tjoi2018.html
Copyright © 2011-2022 走看看