HDU2815 Mod Tree【高次同余方程】

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=2815

题目大意:

有一颗树,每个节点有K个儿子,那么问题来了:能否算出这棵树的最小深度D,使得这个深度

的节点数对P取模的结果为N吗?

思路:

转换一下题目含义,就变成了解K^i = N(mod P),典型的A^i = B(mod C)问题,此题B的范围

明显在[0,C-1]之间,若不在此区间,方程显然无解。

AC代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#define LL __int64
using namespace std;
const int MAXN = 65535;

struct HASH
{
    int a;
    int b;
    int next;
}Hash[MAXN*2];

int flag[MAXN+66];
int top,idx;

void ins(int a,int b)
{
    int k = b & MAXN;
    if(flag[k] != idx)
    {
        flag[k] = idx;
        Hash[k].next = -1;
        Hash[k].a = a;
        Hash[k].b = b;
        return;
    }

    while(Hash[k].next != -1)
    {
        if(Hash[k].b == b)
            return;
        k = Hash[k].next;
    }
    Hash[k].next = ++top;
    Hash[top].next = -1;
    Hash[top].a = a;
    Hash[top].b = b;
}

int Find(int b)
{
    int k = b & MAXN;
    if(flag[k] != idx)
        return -1;
    while(k != -1)
    {
        if(Hash[k].b == b)
            return Hash[k].a;
        k = Hash[k].next;
    }
    return -1;
}

int GCD(int a,int b)
{
    if(b == 0)
        return a;
    return GCD(b,a%b);
}

int ExGCD(int a,int b,int &x,int &y)
{
    int temp,ret;
    if(!b)
    {
        x = 1;
        y = 0;
        return a;
    }
    ret = ExGCD(b,a%b,x,y);
    temp = x;
    x = y;
    y = temp - a/b*y;
    return ret;
}

int Inval(int a,int b,int n)
{
    int x,y,e;
    ExGCD(a,n,x,y);
    e = (LL)x*b%n;
    return e < 0 ? e + n : e;
}

int PowMod(LL a,int b,int c)
{
    LL ret = 1%c;
    a %= c;
    while(b)
    {
        if(b&1)
            ret = ret*a%c;
        a = a*a%c;
        b >>= 1;
    }
    return ret;
}

int BabyStep(int A,int B,int C)
{
    top = MAXN;
    ++idx;
    LL buf = 1%C,D = buf,K;
    int d = 0,temp,i;
    for(i = 0; i <= 100; buf = buf*A%C,++i)
    {
        if(buf == B)
            return i;
    }

    while((temp = GCD(A,C)) != 1)
    {
        if(B % temp)
            return -1;
        ++d;
        C /= temp;
        B /= temp;
        D = D*A/temp%C;
    }

    int M = (int)ceil(sqrt((double)C));
    for(buf = 1%C,i = 0; i <= M; buf = buf*A%C,++i)
        ins(i,buf);

    for(i = 0,K = PowMod((LL)A,M,C); i <= M; D = D*K%C,++i)
    {
        temp = Inval((int)D,B,C);
        int w;
        if(temp >= 0 && (w = Find(temp)) != -1)
            return i * M + w + d;
    }
    return -1;
}

int main()
{
    int A,B,C;
    while(~scanf("%d%d%d",&A,&C,&B))
    {
        if(B > C)
        {
            printf("Orz,I can’t find D!\n");
            continue;
        }
        B %= C;
        int temp = BabyStep(A,B,C);
        if(temp < 0)
            printf("Orz,I can’t find D!\n");
        else
            printf("%d\n",temp);
    }

    return 0;
}
时间: 2024-10-10 05:31:07

HDU2815 Mod Tree【高次同余方程】的相关文章

数论之高次同余方程(Baby Step Giant Step + 拓展BSGS)

什么叫高次同余方程?说白了就是解决这样一个问题: A^x=B(mod C),求最小的x值. baby step giant step算法 题目条件:C是素数(事实上,A与C互质就可以.为什么?在BSGS算法中是要求a^m在%c条件下的逆元的,如果a.c不互质根本就没有逆元.) 如果x有解,那么0<=x<C,为什么? 我们可以回忆一下欧拉定理: 对于c是素数的情况,φ(c)=c-1 那么既然我们知道a^0=1,a^φ(c)=1(在%c的条件下).那么0~φ(c)必定是一个循环节(不一定是最小的)

高次同余方程模板BabyStep-GiantStep

/************************************* ---高次同余方程模板BabyStep-GiantStep--- 输入:对于方程A^x=B(mod C),调用BabyStep(A,B,C),(0<=A,B,C<=10^9) 输出:无解放回-1,有解放回最小非负整数x 复杂度:O(C^0.5),只与C有关,与A,B的大小无关 ************************************/ typedef long long ll; #define HAS

POJ2417 Discrete Logging【高次同余方程】

题目链接: http://poj.org/problem?id=2417 题目大意: 已知整数P.B.N满足公式B^i = N(mod P),求i的值是多少. 思路: 典型的解高次同余方程A^x = B(mod C),直接套模板解决.注意输入顺序:C A B AC代码: #include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<cmath>

HDU 2815 Mod Tree 离散对数 扩展Baby Step Giant Step算法

链接:http://acm.hdu.edu.cn/showproblem.php?pid=2815 题意: 思路:与上题不同,这道题不要求m是素数,是利用扩展Baby Step Giant Step算法求离散对数. 以下转载自:AekdyCoin [扩展Baby Step Giant Step] [问题模型] 求解 A^x = B (mod C) 中 0 <= x < C 的解,C 无限制(当然大小有限制--) [写在前面] 这个问题比较麻烦,目前网络上流传许多版本的做法,不过大部分已近被证明

HDU 2815 Mod Tree (扩展 Baby Step Giant Step )

Mod Tree Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 96 Accepted Submission(s): 38   Problem Description   The picture indicates a tree, every node has 2 children.  The depth of the nodes whos

hdu 2815 Mod Tree 高次方程,n不为素数

1 Accepted 406MS 8576K 2379 B C++/** 2 这里加了一点限制,,大体还是一样的,, 3 4 **/ 5 #include <iostream> 6 #include <cstdio> 7 #include <cmath> 8 #include <cstring> 9 #include <algorithm> 10 using namespace std; 11 long long a,b,n; 12 const

高次同余方程 专题

大牛详解算法 不过cxlove大牛的写法不是hash表实现(读书少,说错了请指正),弱渣用hash表实现了一下..... hdu 2815 mod tree http://acm.hdu.edu.cn/showproblem.php?pid=2815 几个坑点:输出can‘t上面的确是全角,不是半角,手残手动改成了半角.....还有一个地方就是余数n的值应该小于mod的值..... /********************************************************

高次同余方程 $BSGS$

第一篇\(Blog\)... 还是决定把\(luogu\)上的那篇搬过来了. BSGS,又名北上广深 它可以用来求\(a^x \equiv b (mod \ n)\)这个同余方程的一个解,其中\(a,n\)互质. 欧拉定理告诉我们,这里\(a^{\varphi(n)} \equiv 1 (mod \ n)\) 由于\(a^0 \equiv 1 (mod \ n)\),所以这里\(x\)到\(\varphi(n)\)后\(a^x \ mod \ n\)就开始循环了. 所以我们最坏情况就是\(n\)

【hdu2815-Mod Tree】高次同余方程-拓展BadyStepGaintStep

http://acm.hdu.edu.cn/showproblem.php?pid=2815 题意:裸题... 题解:又有一个坑,就是N>=P的时候输出无解. 1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<cmath> 6 #include<algorithm> 7 using namespac