【BSGS求离散对数】HDU Mod Tree 2815

Mod Tree

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5262    Accepted Submission(s): 1360

Problem Description
【BSGS求离散对数】HDU Mod Tree 2815_第1张图片
The picture indicates a tree, every node has 2 children.
The depth of the nodes whose color is blue is 3; the depth of the node whose color is pink is 0.
Now out problem is so easy, give you a tree that every nodes have K children, you are expected to calculate the minimize depth D so that the number of nodes whose depth is D equals to N after mod P.

 

Input
The input consists of several test cases.
Every cases have only three integers indicating K, P, N. (1<=K, P, N<=10^9)

 

Output
The minimize D.
If you can’t find such D, just output “Orz,I can’t find D!”

 

Sample Input

3 78992 453
4 1314520 65536
5 1234 67

 

Sample Output

Orz,I can’t find D!
8
20

 

Author
AekdyCoin

 

Source
HDU 1st “Old-Vegetable-Birds Cup” Programming Open Contest

 

Recommend
lcy   |   We have carefully selected several similar problems for you:   2814  2809  2447  2810  2811
题意:
一个节点可以有K个子节点,问深度D最小是多少时,可以让这个深度的节点数mod p 之后等于N。

解题思路:

BSGS求离散对数!!!此题有坑,can't的上标是全角英文符号。。。。。而且因为是mod p之后等于N   所以N必须<P才可以有解。

AC代码:


#include <stdio.h>
#include <string.h>
#include <math.h>

typedef long long LL;
const int MAXN = 1000100;

bool hash[MAXN];
LL var[MAXN];
LL p[MAXN];

void insert_x(LL n,LL v)
{
	int x=v%MAXN;
	while(hash[x]&&var[x]!=v){
		x++;
		if(x==MAXN) x=0;
	}
	if(!hash[x]){
		p[x]=n;
		var[x]=v;
		hash[x]=true;
	}
}

LL find_x(LL v)
{
	int x=v%MAXN;
	while(hash[x]&&var[x]!=v){
		x++;
		if(x==MAXN) x=0;
	}
	if(hash[x]) return p[x];
	return -1;
}

LL gcd(LL a,LL b)
{
	if(b==0) return a;
	return gcd(b,a%b);
}

LL exgcd(LL a,LL b,LL &x,LL &y)
{
	if(b==0){
		x=1;y=0;
		return a;
	}
	LL r=exgcd(b,a%b,x,y);
	LL t=x;
	x=y;
	y=t-a/b*y;
	return r;
}

LL BSGS(LL A,LL B,LL C)
{
	LL n=1;
	for(int i=0;i<110;i++){
		if(n==B%C) return i;
		n=n*A%C;
	}
	LL M=ceil(sqrt(C*1.0));
	LL d=gcd(A,C);
	LL D=1;
	int cnt=0;
	while(d!=1){
		if(B%d) return -1;
		B/=d;
		C/=d;
		D=D*A/d%C;
		d=gcd(A,C);
		cnt++;
	}
	LL res=1;
	for(int i=0;i<M;i++){
		insert_x(i,res);
		res=res*A%C;
	}
	for(int i=0;i<M;i++){
		LL x,y;
		LL r=exgcd(D,C,x,y);
		x=x*B;
		x=(x%C+C)%C;
		LL ans=find_x(x);
		if(ans!=-1) return i*M+ans+cnt;
		D=D*res%C;
	}
	return -1;
}

int main()
{
	LL K,P,N;
	while(scanf("%lld%lld%lld",&K,&P,&N)!=EOF){
		if(N>=P){
			printf("Orz,I can’t find D!\n");
			continue;
		}
		memset(hash,false,sizeof(hash));
		memset(p,-1,sizeof(p));
		memset(var,-1,sizeof(var));
		LL res=BSGS(K,N,P);
		if(res==-1) printf("Orz,I can’t find D!\n");
		else printf("%lld\n",res);
	}
	return 0;
}


你可能感兴趣的:(【BSGS求离散对数】HDU Mod Tree 2815)