An easy problem HDU - 5475 (线段树+标记)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhangxiaoduoduo/article/details/82891132

                                          An easy problem

                                                                                                                    HDU - 5475 

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≤101≤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≤1091≤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≤1090<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组案例,输入n,MOD,以下n组操作,op,x,当op = 1时,M * = x(M初始值为1),当op = 2时,M除以第x次操作的结果。过程中每次变化都mod。输出每次操作后的结果。

思路:建立线段树,乘法操作的时候就乘,作除法操作时,只需要不乘第i次的数,每次都计算tree[1].sum即可。可以从线段树上设立标记,当进行除第i个数的操作时,就不乘这个位置。(线段树是真的牛!)

AC代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<utility>
#include<set>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#define maxn 100005
#define INF 0x3f3f3f3f
#define LL long long
#define ULL unsigned long long
#define E 1e-8
#define mod 1000000007
#define P pair<int,int>
#define MID(l,r) (l+(r-l)/2)
#define lson(o) (o<<1) //o*2
#define rson(o) (o<<1|1) //o*2+1
using namespace std;

int M;
int p,v;

struct node
{
    int l,r;
    LL sum;
    bool flag;
}tree[maxn<<2];

void build(int o,int l,int r)
{
    tree[o].l = l;
    tree[o].r = r;
    tree[o].flag = 1;
    if(l == r){
        tree[o].sum = 1;
        return ;
    }
    int m = MID(l,r);
    int lc = lson(o),rc = rson(o);
    build(lc,l,m);
    build(rc,m+1,r);
    tree[o].sum = 1;  //不能忽略
    if(tree[lc].flag==1) tree[o].sum = tree[o].sum*tree[lc].sum % M;
    if(tree[rc].flag==1) tree[o].sum = tree[o].sum*tree[rc].sum % M;
}
void update(int t,int o)
{
    if(tree[o].l == tree[o].r){
        if(t == 1){
            tree[o].flag = 1;
            tree[o].sum  = v;
        }
        else{
            tree[o].flag = 0;
        }
        return ;
    }
    int m = MID(tree[o].l,tree[o].r);
    int lc = lson(o),rc = rson(o);
    if(p <= m) update(t,lc);
    else update(t,rc);
    tree[o].sum = 1;  //不能忽略
    if(tree[lc].flag==1) tree[o].sum = tree[o].sum*tree[lc].sum % M;
    if(tree[rc].flag==1) tree[o].sum = tree[o].sum*tree[rc].sum % M;
}
int main()
{
    int T,cases = 0;
    int n,temp,op,x;
    scanf("%d",&T);
    while(T--){
        printf("Case #%d:\n",++cases);
        scanf("%d %d",&n,&M);
        build(1,1,n);
        for(int i=1;i<=n;++i){
            scanf("%d %d",&op,&x);
            if(op == 1){
                temp = 1;
                p = i;
                v = x;
            }
            else{
                temp = 0;
                p = x;
            }
            update(temp,1);
            printf("%lld\n",tree[1].sum);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/zhangxiaoduoduo/article/details/82891132