码迷,mamicode.com
首页 > 其他好文 > 详细

Codevs3753磁阵突围题解

时间:2015-05-09 16:36:26      阅读:113      评论:0      收藏:0      [点我收藏+]

标签:数论   超级幂   

  • 题目描述 Description
    落冰从悬崖上被冲下,虽有落令的精魂保护大难不死,但已消耗了大半法力。此时的棂刚刚也连续经历了三场恶战,身负重伤。夜色中他们急于撤出迷雾丛林,途中却被拉尔法的磁阵困住。这个磁阵专门用来对付落冰,由于洛伦兹力的作用,为避免给自己造成伤害,落冰被迫把自身的电流降到接近0,也因此暂时失去了攻击能力。拉尔法得意地阴笑着,因为他看出了棂的重伤,并认为自己可以轻易战胜棂。
    然而,身经百战的棂早已看穿了一切,他知道拉尔法用大脑控制磁阵。棂和拉尔法之间的磁阵可以看作一个a行b列的矩阵。(他们都在矩阵的外面)棂可以在短时间内控制少量的γ光子,这些光子可以从某一列的任何一个格子出发,到达下一列的任何一个格子,(当然光子一开始从棂出发,可到达第1列的任何一个格子;也可以从第b列——即最后一列——的任何一个格子出发到达拉尔法)当光子到达拉尔法所在的位置时,虽然伤害可以忽略不计,但光子可以对拉尔法的大脑造成扰动(大脑的思考是在量子层面的嘛),然后磁阵强度就会有一定程度的削弱。并且光子到达拉尔法的不同路径数越多,对拉尔法造成的扰动就越大,磁阵削弱得也越厉害。
    这里一条路径指的是光子从棂出发经过b列之后到达了拉尔法所经过的路径。光子只能从某一列到下一列,不能返回到前面的列,也不能在同一列的两个格子运动。
    现在,棂想知道一共有多少种不同的路径,然后他就可以心算出光子对拉尔法造成的扰动和磁阵被削弱的程度,并挑选合适的符咒发动攻击。棂没带笔记本,因此他通过虚数空间把a和b的值告诉了梦中的晓筱。然而晓筱梦见了一个令人费解的数p,经过一番思索,她认为p也是棂告诉的,意思是把答案mod p,因为棂总是很关心她,不想麻烦她写高精。但晓筱参透了p的含义以后,剩余的脑细胞不足以计算出总路径数,于是她请精通OI的你来帮她。

  • 输入描述 Input Description
    只有一行,有3个整数a,b,p,含义同题目描述。

  • 输出描述 Output Description
    只有一个整数,为总路径数mod p以后的值。

  • 样例输入 Sample Input
    样例输入1:
    2 10 1000
    样例输入2:
    3 6 1000

  • 样例输出 Sample Output
    样例输出1:
    24
    样例输出2:
    729

  • 数据范围及提示 Data Size & Hint
    对于20%的数据,b105;
    对于40%的数据,b1050;
    对于100%的数据,a,p10000;b101000000;
    数据全部随机;
    (感觉这样的数据规模并不够大)

  • 题解
    一件事:找到一条路径;
    完成这件事可以分b步,其中每一步都有a种方案;
    根据分步乘法计数原理,总方案数=ab,本题就转化成了求abmodp了。
    套公式abmodp=a(bmodφ(p))+φ(p)modp,bφ(p),大整数的处理方式与fzu1759如出一辙,数据还弱不少,直接拿1759代码改一改就行了。

  • Code

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#define ll long long
using namespace std;
char ch[1000010];
inline ll singleEulerPhi(ll a)
{
    ll ans = a;
    for(ll i = 2; i <= (ll)sqrt(a * 10); ++i) if(a % i == 0)
    {
        ans = ans / i * (i - 1);
        while(a % i == 0) a /= i;
    }   
    if(a > 1) ans = ans / a * (a - 1);
    return ans;
}
inline ll quickPow(ll a, ll b, ll m)
{
    ll ans = 1;
    for(ll t = a; b; b >>= 1, t = (t % m) * (t % m) % m)
        if(b & 1) ans = (ans % m) * (t % m) % m;
    return ans;
}
inline void write(ll a)
{
    int top = 0;
    char ch[50];
    if(a < 0)
    {
        putchar(‘-‘);
        a = -a;
    }
    do {
        ch[top++] = a%10 + 48;
        a /= 10;
    } while(a);
    while(top--) putchar(ch[top]);
    putchar(‘\n‘);
}
int main()
{
    ll a, b, c, phi, len;
    scanf("%lld", &a); scanf("%s", &ch); scanf("%lld", &c);
    len = strlen(ch); phi = singleEulerPhi(c);
    b = 0LL;
    for(int i = 0; i < len; ++i)
    {
        b = b * 10 + ch[i] - 48;
        b %= phi;
    }
    write(quickPow(a, b, c));
    return 0;
}

Codevs3753磁阵突围题解

标签:数论   超级幂   

原文地址:http://blog.csdn.net/t14t41t/article/details/45601863

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!