zoukankan      html  css  js  c++  java
  • [原]sdut2605 A^X mod P 山东省第四届ACM省赛(打表,快速幂模思想,哈希)

    本文出自:http://blog.csdn.net/svitter


    题意:

    f(x) = K, x = 1

    f(x) = (a*f(x-1) + b)%m , x > 1

    求出( A^(f(1)) + A^(f(2)) + A^(f(3)) + ...... + A^(f(n)) ) modular P.

    1 <= n <= 10^6

    0 <= A, K, a, b <= 10^9

    1 <= m, P <= 10^9

    本题目的关键在于大幂的分解和。。你要这样想,因为不停的求A的幂,所以肯定把算过的保存下来最合适。

    打表。(- -)每次都是打表,shit。

    把f分解为 fix * k + j 的形式,f就是f(x)的简称。(哈希)

    然后关键是fix怎么整,多少合适。我觉得33333合适。为啥?

    因为10^9 / 33333 =30000数组不大。然后余数也在33333之内,其好,那就它吧。

    然后就用普通的幂模相乘打表就可以f[i] = (f[i-1] * a)mod p,这是个简单的例子,a和p没有实际含义。

    这个题目我在做的时候蛋疼到二分法动态打表,但是超空间,因为不停的递归调用造成了超空间。。但是我觉得如果能够实现。。用栈的方法,应该会更加节省时间。因为用到的才计算。如果有不同的意见,请回复我,谢谢。


    AC代码:

    //============================================================================
    // Name        : math.cpp
    // Author      : Vit
    // Version     :
    // Copyright   : Your copyright notice
    // Description : Hello World in C++, Ansi-style
    //============================================================================
    
    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <cmath>
    
    using namespace std;
    #define lln long long int
    #define fix 33333
    
    //num
    lln n, A, K, a, b, m, P;
    
    //A^f f = fix * k + j
    //    f = dp1 * k + dp2
    
    lln dpk[30001];
    lln dpj[33334];
    
    void init()
    {
        int i, j;
    
        //init hash
        dpj[1] = A;
        dpj[0] = dpk[0] = 1;
    
        for(i = 2; i <= 33333; i++)
            dpj[i] = (dpj[i-1] * A) % P;
    
        dpk[1] = dpj[33333];
        for(j = 1; j <= 30000; j ++)
            dpk[j] = (dpk[j-1] * dpk[1]) % P;
    }
    
    void ace()
    {
        //work pit;
        int i, t, c;
        lln ans, f;
        scanf("%d", &t);
        for(c = 1; c <= t; c++)
        {
            scanf("%lld%lld%lld%lld%lld%lld%lld",&n, &A, &K, &a, &b, &m, &P);
            //init
            init();
            f = K;
            ans = 0;
            for(i = 0; i < n; i++)
            {
                ans = (ans + dpk[f/fix] * dpj[f % fix]) % P;
                f = (a * f + b) % m;
            }
            printf("Case #%d: %lld
    ", c, ans);
        }
    }
    
    int main()
    {
        ace();
        return 0;
    }
    


    作者:svitter 发表于2014-5-5 21:26:29 原文链接
    阅读:161 评论:0 查看评论
  • 相关阅读:
    《ASP.NET Core 高性能系列》致敬伟大的.NET斗士甲骨文!
    ThreadLocal<T>的是否有设计问题
    从.NET和Java之争谈IT这个行业
    自建型呼叫中心
    托管型呼叫中心
    数字语音记录仪3.0
    模拟电话录音系统2.0
    easyui-combobox 下拉菜单 多选 multiple
    利用easyui-combotree实现 下拉菜单 多选功能(带多选框)
    eclipse项目导入 idea中
  • 原文地址:https://www.cnblogs.com/svitter/p/3724316.html
Copyright © 2011-2022 走看看