• TopCoder SRM596 DIV2 1000: SparseFactorialDiv2


    题意:

    For an integer n, let F(n) = (n - 0^2) * (n - 1^2) * (n - 2^2) * (n - 3^2) * ... * (n - k^2), where k is the largest integer such that n - k^2 > 0. You are given three long longs lo, hi and divisor. It is guaranteed that divisor will be a prime number. Compute and return the number of integers n between lo and hi, inclusive, such that F(n) is divisible by divisor.

    思路:

    等价转换关系

    整除质数<==>有这个质因子

    [lo,hi]<==>[1,hi]  - [1,lo-1]

    首先考虑直接整除的。

    对于区间[1,x],个数为x/divisor个

    其次考虑后面的量

    注意到之间是乘法关系。所以每个量都可以考虑。

    假设n-k可以被divisor整除,那么相当与n是在每个divisor整除数的后k位。

    这里有一个性质:这些n间隔也是divisor

    考虑重复问题:如果%divisor相等,则可能重复。

    k越小,可包含的区间越大。所以从小到大处理k就好。如果取模出现过,就不计算。因为一定已经被之前的计算过了。

    至于计算区间 对于[0,x], k

    就是[k+1,x].(如果k>x那就=0,是k+1的原因是题目要求>0,即不能从0偏移k得到。)

    个数就是(x-k)/divisor

    代码

    #define FOR(I,A,B) for(int I = (A); I < (B); ++I)
    #define REP(I,N)   FOR(I,0,N)
    #define ALL(A)     (A).begin(), (A).end()
    
    class SparseFactorialDiv2
    {
    public:
        long long getCount(long long lo, long long hi, long long divisor)
        {
            int vis[1000];
            REP(i, 1000) vis[i] = 0;
            long long ans = 0;
            for (long long i = 0; i*i<hi; i++) {
                long long mod = (i*i)%divisor;
                if (!vis[mod]) {
                    vis[mod] = 1;
                    long long nlo = 0;
                    if (lo-1 > i*i) nlo = (lo-1-i*i)/divisor;
                    long long nhi = 0;
                    nhi = (hi-i*i)/divisor;
                    ans += nhi-nlo;
                }
            }
            return ans;
        }
    };
    View Code
     
  • 相关阅读:
    数组_leetcode283
    数组_leetcode438
    数组_leetcode215
    数组_leetcode167
    数组_leetcode209
    数组_leetcode88
    数组_leetcode80
    数组_leetcode76
    数组_leetcode75
    数组_leetcode27
  • 原文地址:https://www.cnblogs.com/shinecheng/p/3405012.html
Copyright © 2020-2023  润新知