HDU 5475 An easy problem(线段树)

题目链接:

戳我

题目大意:

一个计算器只有两种运算,初始化 X = 1

第一种操作: X 乘以 一个数,获得新的 X

第二种操作: 当前的 X 除以 一个数

输出  X % M

其中 1 y 表示第一种操作,即 X  = X * y

2 n 表示 X 除以 前面的 第 n 个操作的那个 y,保证 第 n 个表示的是 1,即数据合法

注意:X 在进行操作的时候不要除模, 而是输出的时候除模,即要保证 X 进行操作的时候除模是和不除模情况下是相等的。

比如:

3 10

1 5

1 3

2 1,如果边运算边除模,最后的答案是 5, 5,  0, 但是正确答案是 (1*5)%10,(1*5*3)%10, (1*5*3 / 5) % 10。

样例解释:

1 // 测试样例组数

10 1000000000 // 10个操作,M

1 2   // 1 * 2 = 2

2 1    // 1 * 2 / 2 = 1  除以第一个操作是 1

1 2    // 1 * 2 = 2

1 10   // 2 * 10 = 20

2 3    // 20 / 2 = 10

2 4

1 6

1 7

1 12

2  7

解题思路:

最开始的想法肯定是暴力。把每次操作都记下来,乘法就是 从第一个数 边乘 边取模输出。除法就是把 相应的前面的数变为 1 即可,在从第一个数  边乘边取模。

但无意 是TLE。

我的做法是 用 线段树来做。线段树的节点保存 这个区间 所有数相乘 取模 后的值。

且线段树 初始化全为 1 ,乘法就把相应的 值 改为 y,除法就把相应的 值 改为 1

每次询问 都输出 tree[1].num  即可, 要注意 long long 哟

参考代码:

#include <stdio.h>
#include <iostream>
#include <string.h>
using namespace std;

#define manx 100005
struct Tree
{
    int left;
    int right;
    long long num; //该区间内,已经出现的个数
}tree[4 * manx];
int a[manx], n, m;

void BuildTree(int i, int l, int r);
void Update(int i, int id, int val);
int Query(int i, int l, int r);

int main()
{
    int T, x, y;
    scanf("%d", &T);
    for(int tt = 1; tt <= T; tt++)
    {
        scanf("%d %d", &n, &m);
        BuildTree(1, 1, n);
        printf("Case #%d:\n", tt);
        for(int i = 1; i <= n; i++)
        {
            scanf("%d %d", &x, &y);
            if(x == 1)
            {
                Update(1, i, y);
                printf("%lld\n", tree[1].num);
            }
            else
            {
                Update(1, y, 1);
                printf("%lld\n", tree[1].num);
            }
        }
    }
    return 0;
}

void BuildTree(int i, int l, int r)//建树
{
    tree[i].left = l;
    tree[i].right = r;
    tree[i].num = 1;//初始化全部为0,因为还没有输入
    if(tree[i].left == tree[i].right) return;
    int mid = (l + r) >> 1;
    BuildTree(i << 1, l, mid);
    BuildTree(i << 1 | 1, mid + 1, r);
}

void Update(int i, int id, int val)//更新
{
    if(tree[i].left == id && tree[i].right == id)
    {
        tree[i].num = val;//输入过了,标记为1
        return;
    }
    int mid = (tree[i].left + tree[i].right) >> 1;
    if(id > mid)  Update(i << 1 | 1, id, val);
    else   Update(i << 1, id, val);
    tree[i].num = (tree[i << 1].num * tree[i << 1 | 1].num) % m;//更新此区间内,已经出现过的总数
}

  

时间: 2024-08-09 21:59:43

HDU 5475 An easy problem(线段树)的相关文章

2015上海网络赛 HDU 5475 An easy problem 线段树

题意就不说了 思路:线段树,维护区间乘积.2操作就将要除的点更新为1. 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 #include<queue> 7 #include<vector> 8 #include<set> 9 #include<stri

hud-5475 An easy problem(线段树)

http://acm.hdu.edu.cn/showproblem.php?pid=5475 题意: 原数开始时是1按顺序给你Q个操作,然后其中操作分两种. 1表示将上个操作后的数乘以后面给你的数然后对取余,然后输出结果,2表示除的操作,将现在的数除以指定的先前你所乘上的第几个数 然后对M取模. 思路: 这题用线段树写,断点更新,复杂度是n*(log(n)); 代码: 1 #include<stdio.h> 2 #include<algorithm> 3 #include<i

hdu 5152 A Strange Problem线段树+欧拉函数

*****************************************BC题解**********************************************************************1003 A Strange Problem 对于操作二,利用公式 当x >= Phi(C), A^x = A ^ (x%Phi(C) + Phi(C)) (mod C) 对于2333333这个模数来说,求18次欧拉函数后就变成了1,所以只需要保存19层第三次操作的加数

hdu 5443 The Water Problem 线段树

The Water Problem Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5443 Description In Land waterless, water is a very limited resource. People always fight for the biggest source of water. Given a sequence of wat

Bestcoder round #65 &amp;&amp; hdu 5592 ZYB&#39;s Premutation 线段树

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 175    Accepted Submission(s): 74 Problem Description ZYB has a premutation P,but he only remeber the reverse log of each prefix of the premutat

HDU 1698 Just a Hook (线段树,区间更新)

Just a Hook Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 17214    Accepted Submission(s): 8600 Problem Description In the game of DotA, Pudge’s meat hook is actually the most horrible thing f

HDU 3743 Frosh Week (线段树+离散化)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3743 Frosh Week Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) Total Submission(s) : 5   Accepted Submission(s) : 1 Font: Times New Roman | Verdana | Georgia Font Size: 

hdu 1754 I Hate It 线段树单点更新和区间求和

转载请注明出处:http://blog.csdn.net/u012860063 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1754 参照HH大牛写的额! Problem Description 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少. 这让很多学生很反感. 不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问.当然,老师有时候需要更新某位同学的成绩. Input 本题目包含多

HDU 1264 Counting Squares (线段树-扫描线-矩形面积并)

Problem A : Counting Squares From:HDU, 1264 Problem Description Your input is a series of rectangles, one per line. Each rectangle is specified as two points(X,Y) that specify the opposite corners of a rectangle. All coordinates will be integers in t