zoukankan      html  css  js  c++  java
  • hdu-5475 An easy problem---线段树+取模

    题目链接:

    http://acm.hdu.edu.cn/showproblem.php?pid=5475

    题目大意:

    给X赋初值1,然后给Q个操作,每个操作对应一个整数M;

    如果操作是1则将X乘以对应的M,

    如果是2则除以第M次操作对应的M',求每次操作后X的值对给定值取摸的结果。

    解题思路:

    第一眼看这道题,以为就是水题,直接模拟暴力呀,但是发现这样是错误的,因为这里有除法,对除法取模,就应该是逆元,但是逆元不一定存在

    想了之后发现可以用线段树保存每一个要乘以的数字,对于操作一就加入数字即可,操作二就对第M次操作的数字进行标记,不让他参与乘法运算,每次输出tree[1]的值就可以了。

    线段树维护两个值,一个为标记,一个是区间内的数字的积,对于操作一,更新叶节点,并且更新其父节点。对于操作2也是更新叶节点,标记他,更新父节点时,不让标记过的叶节点参与乘法运算。

     1 #include<bits/stdc++.h>
     2 #define MID(l, r) (l + (r - l) / 2)
     3 #define lc (o<<1)
     4 #define rc (o<<1|1)
     5 using namespace std;
     6 typedef long long ll;
     7 int n, m;
     8 const int maxn = 100000 + 10;
     9 struct node
    10 {
    11     bool flag;
    12     ll num;
    13     int l, r;
    14 }tree[maxn << 2];
    15 void build(int o,int l, int r)
    16 {
    17     tree[o].l = l, tree[o].r = r;
    18     tree[o].flag = 1;
    19     if(l == r)
    20     {
    21         tree[o].num = 1;
    22         return;
    23     }
    24     int m = MID(l ,r);
    25     build(lc, l, m);
    26     build(rc, m + 1, r);
    27     tree[o].num = 1;
    28     if(tree[lc].flag)tree[o].num = tree[o].num * tree[lc].num % m;
    29     if(tree[rc].flag)tree[o].num = tree[o].num * tree[rc].num % m;
    30 }
    31 int flag;
    32 int p, v;
    33 void update(int o)
    34 {
    35     if(tree[o].l == tree[o].r)
    36     {
    37         if(flag)
    38         {
    39             tree[o].flag = 1;
    40             tree[o].num = v;
    41         }
    42         else
    43         {
    44             tree[o].flag = 0;
    45         }
    46         return;
    47     }
    48     if(p <= tree[lc].r)update(lc);
    49     else update(rc);
    50     tree[o].num = 1;
    51     if(tree[lc].flag)tree[o].num = tree[o].num * tree[lc].num % m;
    52     if(tree[rc].flag)tree[o].num = tree[o].num * tree[rc].num % m;
    53 }
    54 int main()
    55 {
    56     int T, cases = 0;
    57     cin >> T;
    58     while(T--)
    59     {
    60         printf("Case #%d:
    ", ++cases);
    61         scanf("%d%d", &n, &m);
    62         int a, b;
    63         build(1, 1, n);
    64         for(int i = 1; i <= n; i++)
    65         {
    66             scanf("%d%d", &a, &b);
    67             if(a == 1)
    68             {
    69                 flag = 1;
    70                 p = i, v = b;
    71             }
    72             else
    73             {
    74                 flag = 0;
    75                 p = b;
    76             }
    77             update(1);
    78             printf("%lld
    ", tree[1].num);
    79         }
    80     }
    81     return 0;
    82 }
  • 相关阅读:
    Springboot-Static-Resource
    Springboot-Listener
    Springboot--servlet 、filter
    java 面试-- java框架-mybaits
    SVN备份教程(二)
    SVN备份教程(一)
    深入浅出MongoDB(三)环境搭建
    关于在c#中引用外部dll文件,在页面中找不到命名空间
    在win8中如何实现下拉刷新的功能
    C# treeview控件部分节点添加checkbox
  • 原文地址:https://www.cnblogs.com/fzl194/p/9040396.html
Copyright © 2011-2022 走看看