zoukankan      html  css  js  c++  java
  • 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
    */
    
    
  • 相关阅读:
    83. Remove Duplicates from Sorted List
    35. Search Insert Position
    96. Unique Binary Search Trees
    94. Binary Tree Inorder Traversal
    117. Populating Next Right Pointers in Each Node II
    116. Populating Next Right Pointers in Each Node
    111. Minimum Depth of Binary Tree
    169. Majority Element
    171. Excel Sheet Column Number
    190. Reverse Bits
  • 原文地址:https://www.cnblogs.com/Roni-i/p/9532280.html
Copyright © 2011-2022 走看看