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
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;
}