hdu 5475 An easy problem (2015 上海网络赛 H题)

传送门  ←点这里

题意:

在一个 初始值为 x = 1 的计算器上进行两种操作:

1. 乘以y

2. 除以一个 之前乘过 的数

每次操作之后,输出 计算器上显示的数字%M 的值


思路:


操作只有10^5个  可以视为有10^5个数字,他们的初始值都为1。

每次操作都对其中一个数字进行修改:

          1操作, 把当前第i个数字改成y

          2操作, 把第y个数字改成1

然后利用线段树的性质,对整个1~n的区间进行维护,每次输出sum[1]的值即可....

(。。。不是正解吧。。。逃》


code:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

const int maxn = 100005;

int mod;
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
long long sum[maxn<<2];

void pushup(int rt){
    sum[rt] = (sum[rt<<1] * sum[rt<<1|1]) % mod;
}
void build(int l, int r, int rt){
    sum[rt] = 1;
    if(l == r) return;
    int m = (l + r) >> 1;
    build(lson);
    build(rson);
    pushup(rt);
}
void update(int p, long long v, int l, int r, int rt){
    if(l == r){
        sum[rt] = v % mod;
        return;
    }
    int m = (l + r) >> 1;
    if(p <= m) update(p, v, lson);
    else update(p, v, rson);
    pushup(rt);
}

int main(){
    int t;
    int cas = 0;
    int n, op;
    long long y;
    scanf("%d",&t);
    while(t--){
        scanf("%d%I64d",&n, &mod);
        build(1, n, 1);
        printf("Case #%d:\n", ++cas);
        for(int i = 1; i <= n; i++){
            scanf("%d%I64d", &op, &y);
            if(op == 1)
                update(i, y, 1, n, 1);
            if(op == 2)
                update(y, 1, 1, n, 1);
            printf("%I64d\n", sum[1]);
        }
    }
    return 0;
}




阅读更多
版权声明:转载请注明出处 http://blog.csdn.net/u013382399 https://blog.csdn.net/u013382399/article/details/48765699
文章标签: hdu 网络赛 线段树
个人分类: 算法竞赛题解
所属专栏: acm-icpc竞赛时光记
上一篇组合数取模(杨辉三角+Lucas定理+模合数)
下一篇can't find compiler executable in your configured search path's for GUN GCC Complier的应对办法
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭