WUST 【1593】 Count Zeros

1593: Count Zeros

Time Limit: 1 Sec   Memory Limit: 128 MB   64bit IO Format: %lld
Submitted: 82   Accepted: 9
[ Submit][ Status][ Web Board]

Description

Blue Wang is addicted in Math. He calculates all kinds of math problems all day. The answer may be very large, but he writes it on the paper by hand.
Sometimes it’s boring because he must write many zeros at the tail of the answer sequence.
So he wants to know how many zeros at the tail of answer when he calculates the product of a continuous integer sequence.
 

Input

There are multiple test cases. For each test case: the first line contains two integers n,m(n,m<100000) denoting the number of integers and queries. The second line are n integers A1,A2,A3...An(Ai<=100,1<=i<=n) .The next m lines, each line contains three numbers  op,x,y ,If op=0, you need help him calculate the answer (zeros at the tail of answer When he calculates the product of a continuous integer sequence between x,y) and output it. If op=1, you need change the integer at the position of x to y.All integers are not smaller than 0.
 

Output

For each query, if op=0 , output a integer which denotes the number of zeros Blue Wang needs write at the tail of answer. 

Sample Input

5 3
1 2 3 4 10
0 1 5
1 4 5
0 1 5

Sample Output

1
2

Source

武汉科技大学第二届移动互联网应用设计大赛(A类)暨华中地区程序设计竞赛专业组


/*
这道题线段树通过维护每一段2和5的数量来计算尾部有多少个0
同时要注意可能存在0,那时候只需要输出1就可以了,是一道
线段树好题,武科的现场赛的题还是可以的
*/
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int maxn = 100005;
int n,m,x,y,lalala,ret2,ret5;

struct SegTree
{
    int l,r;
    int f,num2,num5;
}segtree[4*maxn];

int a[maxn],count2[maxn],count5[maxn],flag[maxn];

void build(int o,int L,int R)
{
    segtree[o].l = L;
    segtree[o].r = R;
    if(L == R)
    {
        if(flag[L])
            segtree[o].f = 1;
        else
            segtree[o].f = 0;
        segtree[o].num2 = count2[L];
        segtree[o].num5 = count5[L];
        return ;
    }
    int M = (L+R)/2;
    build(o*2, L, M);
    build(o*2+1, M+1, R);
    if(segtree[o*2].f || segtree[o*2+1].f)
        segtree[o].f = 1;
    else
        segtree[o].f = 0;
    segtree[o].num2 = segtree[o*2].num2 + segtree[o*2+1].num2;
    segtree[o].num5 = segtree[o*2].num5 + segtree[o*2+1].num5;
}

void update(int o,int L,int R)
{
    int M = (L+R)/2;
    if(L == R)
    {
        if(!y) segtree[o].f = 1;
        else
        {
            segtree[o].f = 0;
            int num2 = 0,num5 = 0;
            while(y % 2 == 0)
            {
                num2++;
                y /= 2;
            }
            while(y % 5 == 0)
            {
                num5++;
                y /= 5;
            }
            segtree[o].num2 = num2;
            segtree[o].num5 = num5;
        }
    }
    else
    {
        if(x <= M) update(o*2, L, M);
        else  update(o*2+1, M+1, R);
        if(segtree[o*2].f || segtree[o*2+1].f)
            segtree[o].f = 1;
        else
            segtree[o].f = 0;
        segtree[o].num2 = segtree[o*2].num2 + segtree[o*2+1].num2;
        segtree[o].num5 = segtree[o*2].num5 + segtree[o*2+1].num5;
    }
}

void query(int o, int L, int R)
{
    int M = (L+R)/2;
    if(x <= L && R <= y)
    {
        if(segtree[o].f) lalala = 1;
        ret2 += segtree[o].num2;
        ret5 += segtree[o].num5;
        return ;
    }
    if(x <= M) query(o*2, L, M);
    if(M < y) query(o*2+1, M+1, R);
}

int main()
{
    while(scanf("%d %d", &n, &m) != EOF)
    {
        memset(a,0,sizeof(a));
        memset(count2, 0, sizeof(count2));
        memset(count5, 0, sizeof(count5));
        memset(flag, 0, sizeof(flag));
        for(int i = 1; i <= n; i++)
        {
            scanf("%d", &a[i]);
            if(!a[i]) flag[i] = 1;
            else
            {
                while(a[i] % 2 == 0)
                {
                    count2[i]++;
                    a[i] /= 2;
                }
                while(a[i] % 5 == 0)
                {
                    count5[i]++;
                    a[i] /= 5;
                }
            }
        }
        build(1, 1, n);
        while(m--)
        {
            int op;
            scanf("%d%d%d", &op, &x, &y);
            if(op)
                update(1, 1, n);
            else
            {
                lalala = 0;
                ret2 = 0,ret5 = 0;
                query(1, 1, n);
                if(lalala) printf("1\n");
                else
                    printf("%d\n", min(ret2,ret5));
            }
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值