• FZU 2297 Number theory【线段树/单点更新/思维】


    Given a integers x = 1, you have to apply Q (Q ≤ 100000) operations: Multiply, Divide.
    Input
    First line of the input file contains an integer T(0 < T ≤ 10) that indicates how many cases of inputs are there.

    The description of each case is given below:

    The first line contains two integers Q and M. The next Q lines contains the operations in ith line following form:

    M yi: x = x * yi.

    N di: x = x / ydi.

    It’s ensure that di is different. That means you can divide yi only once after yi came up.

    0 < yi ≤ 10^9, M ≤ 10^9

    Output
    For each operation, print an integer (one per line) x % M.

    Sample Input
    1
    10 1000000000
    M 2
    D 1
    M 2
    M 10
    D 3
    D 4
    M 6
    M 7
    M 12
    D 7
    Sample Output
    2
    1
    2
    20
    10
    1
    6
    42
    504
    84

    【分析】
    针对一个数组的操作,即对一个区间。可以用线段树去进行维护。初始化建树,叶子节点的值为1,维护每段区间上各个元素的乘积sum。M yi,将第i个元素的值改为yi。N di,将第di个元素的值改为1。输出即查询区间[1,Q]的sum值。也就是变成了单点更新、区间查询问题。
    时间复杂度为O(QlongQ)。

    #include<cstdio>
    #include<string>
    #include<cstdlib>
    #include<cmath>
    #include<iostream>
    #include<cstring>
    #include<set>
    #include<queue>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<stack>
    #include<sstream>
    #include<list>
    #include<bitset>
    using namespace std;
    typedef long long LL;
    typedef unsigned long long ULL;
    const int maxn = 1e5;
    const double eps = 1e-8;
    
    LL mod,val;
    LL sum[maxn*4];
    
    void update(int p,int val,int l,int r,int rt)
    {
        if(l==r)
        {
            sum[rt]=val;
            return ;
        }
        int  m=(l+r)/2;
        if(p<=m)
            update(p,val,l,m,rt*2);
        else
            update(p,val,m+1,r,rt*2+1);
        sum[rt] = sum[rt*2] * sum[rt*2+1] % mod;
    }
    //char op[10];
    int main()
    {
        //ios::sync_with_stdio(false);
        int t,q;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%lld",&q,&mod);
            for(int i=1;i<=4*maxn;i++) sum[i]=1;
            for(int i=1;i<=q;i++)
            {
                int x;char op[10];
                scanf("%s%d",op,&x);
                if(op[0]=='M')
                {
                    update(i,x,1,maxn,1);
                    printf("%lld
    ",sum[1]);
                }
                else
                {
                    update(x,1,1,maxn,1);
                    printf("%lld
    ",sum[1]);
                }
            }
        }
        return 0;
    }
    /*
    1
    10 1000000000
    M 2
    D 1
    M 2
    M 10
    D 3
    D 4
    M 6
    M 7
    M 12
    D 7
    
    2
    1
    2
    20
    10
    1
    6
    42
    504
    84
    */
    
    
  • 相关阅读:
    gearman任务分发改进
    gearman实现任务分发
    BeanStalkd 做队列服务
    Tomcat各种日志的关系与catalina.out文件的分割
    数据库系统原理-关系数据库的规范化理论总结
    MySQL配置参数innodb_flush_log_at_trx_commit
    gRPC快速入门
    使用vagrant和kubeadm搭建k8s集群
    VS项目属性中的C/C++运行库:MT、MTd、MD、MDd
    消除C++中警告代码
  • 原文地址:https://www.cnblogs.com/Roni-i/p/9532280.html
Copyright © 2020-2023  润新知