Trailing Zeroes (II) LightOJ - 1090(预处理+前缀和)

求C(n,r)*p^q的后缀零

考虑一下 是不是就是求 10^k*m  的k的最大值

而10又是由2 和 5 组成  所以即是求 2^k1 * 5^k2 * m1 中k1和k2小的那一个数 短板效应嘛。。
预处理每个 1 - 1e6 的每个数字的对2分解,对5分解的次数  然后还要保存下前缀和  作为 n的阶乘中分别包含的次数

#include <iostream>
#include <cstdio>
#include <sstream>
#include <cstring>
#include <map>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
#include <cmath>
#define MOD 2018
#define LL long long
#define ULL unsigned long long
#define Pair pair<int, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define _  ios_base::sync_with_stdio(0),cin.tie(0)
//freopen("1.txt", "r", stdin);
using namespace std;
const int maxn = 1e6 + 10, INF = 0x7fffffff;
int sum1[maxn], sum2[maxn], a[maxn], b[maxn];


int count_(int a, int b)
{
    int cnt = 0;
    while(a % b == 0)
    {
        cnt++;
        a/=b;
    }
    return cnt;
}

int main()
{
    for(int i=2; i<maxn; i++)
    {
        a[i] = count_(i, 2);
        b[i] = count_(i, 5);
        sum1[i] += sum1[i-1] + a[i];
        sum2[i] += sum2[i-1] + b[i];
    }
    int n, r, p, q, T, kase = 0;
    cin>> T;
    while(T--)
    {
        cin>> n >> r >> p >> q;
        int c = sum1[n] - sum1[r] - sum1[n-r];
        int d = sum2[n] - sum2[r] - sum2[n-r];
        int e = a[p] * q;
        int f = b[p] * q;
        cout<< "Case "<< ++kase <<": " <<min(c+e, d+f) <<endl;
    }


    return 0;
}
View Code

 


  

posted @ 2018-07-22 11:13  WTSRUVF  阅读(186)  评论(0编辑  收藏  举报