*任意n的一道式子

来源:互联网 发布:q币回收软件 编辑:程序博客网 时间:2024/06/09 17:08

Given a prime number C(1C2×105)C(1≤C≤2×105), and three integers k1, b1, k2 (1k1,k2,b1109)  (1≤k1,k2,b1≤109). Please find all pairs (a, b) which satisfied the equation ak1n+b1   ak1⋅n+b1+bk2nk2+1    bk2⋅n−k2+1 = 0 (mod C)(n = 1, 2, 3, ...).
Input
There are multiple test cases (no more than 30). For each test, a single line contains four integers C, k1, b1, k2.
Output
First, please output "Case #k: ", k is the number of test case. See sample output for more detail. 
Please output all pairs (a, b) in lexicographical order. (1a,b<C)(1≤a,b<C). If there is not a pair (a, b), please output -1.
Sample Input
23 1 1 2
Sample Output
Case #1:1 22     
这道题真的很难,必须要很好的数学功底以及足够的思维能力,还有敢于尝试且有很好的总结能力。

然而很正常的,我做不出来。。

看来很多百度的,只有一种做法我比较认同,然后ac了。

消化了他的做法。在这里讲讲:(同时总结一点他人的套路,看看以后自己用不用得到)

首先,(这是第一步),就是想到用n = 1代入看看结果如何。可以得到a^k1+a^bi+b = 0.(mod c)

这样可以得到b = -(a^(k1+b1))(mod c)。

然后明显1条式子并不能推出什么。(可能这就是一个逻辑的走向吧,我想既然哦自己没能做出这题,没能自然而然的想到这样的解法,但是或许可以向他这样,遇到n的,而且n 任意的,就先从1开始代起,看看能不能得到什么)

代入2之后

a^(2*k1+b1) + b^(k2+1) = 0;

由于 b = -(a^(k1+b1))(mod c)。于是可以换掉一个a。(其实根本的就是结合两个式子求得规律)

b^(k2+1)=-a^(2*k1+b1)=b*a^(k1)。

所以很明显了

b^k2=a^k1;

于是可以只要枚举所有a,由a推出b(b = -(a^(k1+b1))(mod c))。

然后检验是否满足,满足就输出,ok,ac!

在此膜拜一下那个想出这种做法的dalao奋斗奋斗向他学习。

ac代码:

#include <stdio.h>#include <iostream>#include <cstring>#include <cmath>#include <algorithm>#include <queue>#include <sstream>#define INF 1e9using namespace std;typedef long long ll;ll c,k1,k2,b1;ll quickpow(ll a,ll b){    ll ans = 1;    while (b!=0)    {        if(b&1)        {            ans*=a;            ans%=c;        }        a*=a;        a%=c;        b>>=1;    }    return ans;}//以后快速幂都写一个函数好了,方便又不会乱bool judge(ll a,ll b){    if(quickpow(a,k1)!=quickpow(b,k2))    {        return false;    }    return true;}//判断的int main(void){    int k = 1;    while (scanf("%lld %lld %lld %lld",&c,&k1,&b1,&k2)!=EOF)    {        int flag = 0;        printf("Case #%d:\n",k++);        for (ll a = 1;a < c;a++)        {            ll b = -quickpow(a,(b1+k1)%(c-1));            b = (b+c)%c;            if(judge(a,b))            {                printf("%lld %lld\n",a,b);                flag = 1;            }        }        if(!flag)            cout<<-1<<endl;    }}//要记得用ll,一开始没用ll还错了- -


0 0
原创粉丝点击