hdu 5478(2015 ACM/ICPC Asia Regional Shanghai Online )

今天,帕斯喵学了一下数字逻辑,发现题目完全不会做(大哭大哭大哭大哭)看来帕斯喵还是太笨了。

于是呢,帕斯喵又来切题了。

Problem Description
Given a prime number C(1C2×105) , and three integers k1, b1, k2 (1k1,k2,b1109) . Please find all pairs (a, b) which satisfied the equation ak1n+b1 + bk2nk2+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) . If there is not a pair (a, b), please output -1.
 


 

Sample Input
  
  
23 1 1 2
 


 

Sample Output
  
  
Case #1: 1 22
 


 

Source
 


 

Recommend
hujie   |   We have carefully selected several similar problems for you:   5493  5492  5491  5490  5489 
 

这个题,窝也不好翻译啦。题目很短,大家慢慢看。

题目中给定了四个数,c,k1,b1,k2,要使得等式恒成立,我们不可能一一枚举,每一个n的值。这个题需要用到数学归纳法的思想,当n=1时,等式成立,同时n=2,等式也成立的话,那么就有该等式对于任意的n值恒成立。

下面是证明过程:

 

通过(1)式和(2)式,那么呢,我们可以得到(3)式,然后我们反复的利用(3)式,就可以得到该等式恒成立啦。

剩下的就是编码了,题目说数据不超过30组,并且时间限定在5s以内,这是不是在给人提示呢。嘛,帕斯喵太笨了,只能想到用暴力。(偷笑偷笑偷笑偷笑

刚开始萌蠢得帕斯喵用2重for循环来暴力,外层循环来遍历a的值,内层循环用来遍历b的值,结果悲剧。事实上用一个for循环来遍历a的值,通过(1)式来得到b的值,然后判断

(2)式,是否成立,这样时间复杂度就降下来了,O(n)。偷笑偷笑偷笑

代码:

#include <iostream>
#include <stdio.h>
using namespace std;
long long quickmod(long long a,long long b,long long mod)//快速幂
{
  long long ans=1;
  while(b)
  {
   if(b&1)
   {
    ans=ans*a%mod;
    b--;
   }
   b=b>>1;
   a=a%mod*a%mod;
  }
  return ans;
}
int main()
{
    long long c,k1,b1,k2,res;//res用来存题目中b的值
    int reg,flag=0;//flag用来记录次数
    while(cin>>c>>k1>>b1>>k2)
    {
      reg=0;//表示没有满足题意的a,b
      flag++;
     printf("Case #%d:\n",flag);
     for(int i=1;i<c;i++)
     {
         res=c-quickmod(i,k1+b1,c);
       if(quickmod(i,2*k1+b1,c)==c-quickmod(res,k2+1,c))
       {
         cout<<i<<" "<<res<<endl;
         reg=1;//表示存在满足题意的a,b;
       }
     }
     if(reg==0)
     cout<<-1<<endl;
    }
    return 0;
}


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值