zoukankan      html  css  js  c++  java
  • ACM学习历程—HDU5475 An easy problem(线段树)(2015上海网赛08题)

    Problem Description

    One day, a useless calculator was being built by Kuros. Let's assume that number X is showed on the screen of calculator. At first, X = 1. This calculator only supports two types of operation.
    1. multiply X with a number.
    2. divide X with a number which was multiplied before.
    After each operation, please output the number X modulo M.

     

     

    Input

    The first line is an integer T(1≤T≤10), indicating the number of test cases.
    For each test case, the first line are two integers Q and M. Q is the number of operations and M is described above. (1≤Q≤105,1≤M≤109)
    The next Q lines, each line starts with an integer x indicating the type of operation.
    if x is 1, an integer y is given, indicating the number to multiply. (0<y≤109)
    if x is 2, an integer n is given. The calculator will divide the number which is multiplied in the nth operation. (the nth operation must be a type 1 operation.)

    It's guaranteed that in type 2 operation, there won't be two same n.

     

     

    Output

    For each test case, the first line, please output "Case #x:" and x is the id of the test cases starting from 1.
    Then Q lines follow, each line please output an answer showed by the calculator.

     

     

    Sample Input

    1

    10 1000000000

    1 2

    2 1

    1 2

    1 10

    2 3

    2 4

    1 6

    1 7

    1 12

    2 7

     

     

    Sample Output

    Case #1:

    2

    1

    2

    20

    10

    1

    6

    42

    504

    84

    题目主要是出现的除法,在模条件下是不能进行除法的,除非存在逆元可以实现除法,但是此处除数不一定与被除数互质。

    但是如果过程中不模的话,就要使用大数,会T。

    考虑到题目中提到了,除数不会出现相同的。

    也就是如果乘了1,2,3,然后再除掉2的话,结果就是由1和3构成,这样就不用考虑每个数的情况了,此时的每个数就是一个整体,结果只和这个数有没有出现有关。

    于是可以考虑用线段树来维护分段的积。当某一个数被除掉了,所有与这个数相关的区间都要重新计算,最多有log(q)个区间。

    这样效率就是qlogq,是满足条件的。

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <cstring>
    #include <algorithm>
    #include <set>
    #include <map>
    #include <queue>
    #include <string>
    #define LL long long
    
    using namespace std;
    
    const int maxN = 100005;
    int q, m;
    int op[maxN], top;
    
    //线段树
    struct node
    {
        int lt, rt;
        LL val;
    }tree[4*maxN];
    
    //向上更新
    void pushUp(int id)
    {
        tree[id].val = (tree[id<<1].val*tree[id<<1|1].val)%m;
    }
    
    //建立线段树
    void build(int lt, int rt, int id)
    {
        tree[id].lt = lt;
        tree[id].rt = rt;
        tree[id].val = 1;//每段的初值,根据题目要求
        if (lt == rt)
        {
            //tree[id].add = ??;
            return;
        }
        int mid = (lt+rt)>>1;
        build(lt, mid, id<<1);
        build(mid+1, rt, id<<1|1);
        pushUp(id);
    }
    
    void add(int lt, int rt, int id, int pls)
    {
        if (lt <= tree[id].lt && rt >= tree[id].rt)
        {
            if (pls)
            {
                tree[id].val *= pls;
                tree[id].val %= m;
            }
            else
                tree[id].val = 1;
            return;
        }
        int mid = (tree[id].lt+tree[id].rt)>>1;
        if (lt <= mid)
            add(lt, rt, id<<1, pls);
        if (rt > mid)
            add(lt, rt, id<<1|1, pls);
        pushUp(id);
    }
    
    void work()
    {
        build(1, q, 1);
        top = 1;
        int d, y;
        for (int i = 0; i < q; ++i)
        {
            scanf("%d%d", &d, &y);
            if (d == 1)
                add(top, top, 1, y);
            else
                add(y, y, 1, 0);
            op[top++] = y;
            printf("%I64d
    ", tree[1].val);
        }
    }
    
    int main()
    {
        //freopen("test.in", "r", stdin);
        int T;
        scanf("%d", &T);
        for (int times = 1; times <= T; ++times)
        {
            printf("Case #%d:
    ", times);
            scanf("%d%d", &q, &m);
            work();
        }
        return 0;
    }
  • 相关阅读:
    在mysql中计算百分比
    给指定的div增加滚动条
    Java高效编程之三【类和接口】
    Linux(CentOS) 如何查看当前占用CPU或内存最多的K个进程
    MapReduce:详解Shuffle过程
    Java高效编程之二【对所有对象都通用的方法】
    Java高效编程之一【创建和销毁对象】
    ANT命令总结(转载)
    linux 压缩文件的命令总结
    Cloudera CDH 、Impala本地通过Parcel安装配置详解
  • 原文地址:https://www.cnblogs.com/andyqsmart/p/4857403.html
Copyright © 2011-2022 走看看