当前位置: 首页 > 编程日记 > 正文

hdu3321

Problem Description

Professor Brute is not good at algorithm design. Once he was asked to solve a path finding problem. He worked on it for several days and finally came up with the following algorithm:

3221-1.jpg

Any fool but Brute knows that the function “funny” will be called too many times. Brute wants to investigate the number of times the function will be called, but he is too lazy to do it.
Now your task is to calculate how many times the function “funny” will be called, for the given a, b and n. Because the answer may be too large, you should output the answer module by P.

Input

There are multiple test cases. The first line of the input contains an integer T, meaning the number of the test cases.
For each test cases, there are four integers a, b, P and n in a single line.
You can assume that 1≤n≤1000000000, 1≤P≤1000000, 0≤a, b<1000000.

Output

For each test case, output the answer with case number in a single line.

Sample Input

3 3 4 10 3 4 5 13 5 3 2 19 100

Sample Output

Case #1: 2 Case #2: 11 Case #3: 12

由题意不难推出以下的递推公式: f[n]=f[n-1]*f[n-2],f[1]=a,f[2]=b;(当然,最后的结果不要忘记Mod p)

对于较小的N,直接一个循环求解即可。然而此题的N可达到10^9,显然在1秒的时限内,这种方法不再奏效。

仔细观察,发现每个f[n]都可以表示成a^t1*b^t2的形式,且不难推出对于某个N:

(1)N=1,则t1=1,t2=0; (2)N=2,则t1=0,t2=1;

(3) N>=3,t1=F(N-2),t2=F(N-1),其中F(n)表示第n个Fibonacci数

有了以上的信息,不难想到可以先运用矩阵连乘+快速幂 迅速求出F(N-1),F(N-2),再用运用快速幂算法处理(a^t1*b^t2) mod p,然而由于此处的N可以达到10^9,这样大的Fibonacci数F(N-1)已经远远超过了c++任何的内置类型,所以要想办法利用mod p这个条件

M1:利用数论中的Euler Phi函数,此处不作讨论

M2:由于p<=10^6,由鸽笼原理易知对于任意的正整数a, a^n mod p(n=0,1,2,3……)必然存在一个固定长度循环结(具体的求循环结的方法见代码),在此处不妨假设:

a^n mod p从 n=starta 处开始,存在一个长度为rlena的循环结;

b^n mod p从 n=startb 处开始,存在一个长度为rlenb的循环结;

由此得到以下结论:

a^t1 mod p=a^t1 mod p, if t1<=starta+rlena

=a^(starta+(t1-starta) mod rlena)) mod p, if t1>starta+rlena  (*)

(b的相关表达式类似a)

所以对于两个相乘的矩阵(此处为2阶):

将(*)处得结论运用到 矩阵连乘+快速幂 求a的模p的等价系数t1’的过程中,即

wps_clip_image-13462

令x3=(x1*y1+x2*y2)则if x3<=starta + rlena, x’=x3; else x’=(starta+(x3-rlena) mod rlena) rlena,求y’,z’,w’的方法类似

按照上述的类似方法求出b的模p的等价系数t2’,最后再利用快速幂求出(a^t1’*b^t2’) mod p这个最终结果

以下是实现代码:

   1:  
   2: #include<iostream>
   3: #include<cstdio>
   4: #include<cstring>
   5: #include <cstdlib>
   6: using namespace std;
   7: typedef long long bint;
   8:  
   9: #define size 1001000
  10: bint que[size];
  11: int app[size];
  12:  
  13: void find_repeat_len(int a,int p,int& rlen,int& start){
  14:     bint mo=a%p; int index=1;
  15:     que[index]=mo; app[mo]=index; mo=mo*a%p;
  16:     while (!app[mo]){++index;
  17:     que[index]=mo; app[mo]=index; mo=mo*a%p;
  18:     }
  19:     rlen=index-app[mo]+1; start=app[mo];
  20: }
  21: int ma[3][3],mb[3][3];
  22: #define fun(x,st,rlen) ((x)<st+rlen?(x):st+((x)-st)%rlen)
  23: void matrix_multi(int a[][3],int b[][3],int c[][3],int rlen,int st){
  24:     bint x1,y1,z1,w1; bint x2,y2,z2,w2;
  25:     x1=a[1][1]; y1=a[1][2]; z1=a[2][1]; w1=a[2][2];
  26:     x2=b[1][1]; y2=b[1][2]; z2=b[2][1]; w2=b[2][2];
  27:     bint tp;
  28:     tp=x1*x2+y1*z2; c[1][1]=fun(tp,st,rlen);
  29:     tp=x1*y2+y1*w2; c[1][2]=fun(tp,st,rlen);
  30:     tp=z1*x2+w1*z2; c[2][1]=fun(tp,st,rlen);
  31:     tp=z1*y2+w1*w2; c[2][2]=fun(tp,st,rlen);
  32: }
  33: int get_power(int rlen,int start,int kth){
  34:     //求第kth个Fibnacci数,并利用循环节化简指数
  35:     if (kth<=2) return 1;
  36:     kth-=2;
  37:     ma[1][1]=0; ma[1][2]=1; ma[2][1]=1; ma[2][2]=1;
  38:     mb[1][1]=1; mb[1][2]=0; mb[2][1]=0; mb[2][2]=1;
  39:     while (kth){
  40:         if (kth&1) matrix_multi(mb,ma,mb,rlen,start);
  41:         matrix_multi(ma,ma,ma,rlen,start); kth>>=1;
  42:     }
  43:     bint tp=mb[2][1]+mb[2][2];
  44:     return fun(tp,start,rlen);
  45: }
  46:  
  47:  
  48: void solveit(int a,int b,int p,int n){
  49:     if (n==1) printf("%d\n",a%p);
  50:     else if (n==2) printf("%d\n",b%p);
  51:     else {
  52:         int rlena,rlenb,starta,startb;
  53:         memset(app,0,sizeof(int)*(p+10));
  54:         find_repeat_len(a,p,rlena,starta);
  55:         int powa=get_power(rlena,starta,n-2);
  56:         bint ans=que[powa];
  57:         memset(app,0,sizeof(int)*(p+10));
  58:         find_repeat_len(b,p,rlenb,startb);
  59:         int powb=get_power(rlenb,startb,n-1);
  60:         ans=ans*que[powb]%p;
  61:         printf("%lld\n",ans);
  62:     }
  63: }
  64: int main() {
  65:     int testnum;
  66:     scanf("%d",&testnum);
  67:     int casenum=0;
  68:     while (testnum--){++casenum; printf("Case #%d: ",casenum);
  69:     int a,b,p,n;
  70:     scanf("%d%d%d%d",&a,&b,&p,&n);
  71:     solveit(a,b,p,n);
  72:     }
  73:     return 0;
  74: }
  75:  
  76:  


Quote of the Day:
In life, as in chess, forethought wins.
--Charles Buxton

转载于:https://www.cnblogs.com/song19931218/archive/2011/09/21/2183027.html

相关文章:

[leedcode 118] Pascal's Triangle

Given numRows, generate the first numRows of Pascals triangle. For example, given numRows 5,Return [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1] ] public class Solution {public List<List<Integer>> generate(int numRows) {//杨辉三角形&#xff0c;把每…

bzoj 4025 二分图——线段树分治+LCT

题目&#xff1a;https://www.lydsy.com/JudgeOnline/problem.php?id4025 线段树分治&#xff0c;用 LCT 维护链的长度即可。不过很慢。 正常&#xff08;更快&#xff09;的方法应该是线段树分治并查集&#xff08;按秩合并&#xff0c;链长可以暴力爬&#xff09;或者 LCT 维…

黑盒测试之功能分解法

功能分解法前言概念需求示例测试用例分析设计总结前言 首先和各位道个歉&#xff0c;最近事情比较多&#xff0c;本来计划的一周一更推迟了这么久。今天咱们继续&#xff0c;开始黑盒测试方法部分的分享。 概念 在学习软件测试的时候经常听到功能分解法&#xff0c;很多人项…

java中Class.forName与new

一、使用Class.forName 1、装载类 Class clazz Class.forName("xx.xx.xx"); 2、初始化对象 clazz.newInstance() 二、使用 new new Object(); 使用Class.forName的好处&#xff0c; 比如加载数据库驱动&#xff0c;若更换数据库&#xff0c;则需要更换驱动。 如果使…

UVA 10041 Vito's Family

UVA_10041这个题目是一个贪心的题目。如果设按升序排列的si的数组为s[]&#xff0c;那么Vito的位置一定为s[(r-1)/2]。对于这一点&#xff0c;我们分两种情况进行讨论&#xff1a;①如果si的数量为奇数&#xff0c;那么Vito的位置一定取数组s[]中间的那个值s[(r-1)/2]。因为如果…

数据结构杂题集

Codechef SD ER • 给出一棵树&#xff0c;维护点集 ?&#xff08;加点删点&#xff09; • 如果 ? 的大小是偶数&#xff0c;输出&#xff1a;如果将 ? 中的点两两连上边权为树上距离的边&#xff0c;那么 ? 里的最小权完美匹配是多少• ?, ? ≤ 10^6 考虑边的贡献 交叉…

黑盒测试方法之等价类划分法

等价类划分法 概念需求示例测试用例分析设计总结概念 等价类是指某个输入域的子集,在该子集中每个输入数据的作用是等效的,也就是该子集中每个输入数据的揭错概率是一样的。等价类分为有效等价类和无效等价类。 等价类划分法是将输入数据分成若干个子集,从每个子集选取一个…

JSEL 表达式

JSTL标签库的使用是为类弥补html表的不足&#xff0c;规范自定义标签的使用而诞生的。在告别modle1模式开发应用程序后&#xff0c;人们开始注重软件的分层设计&#xff0c;不希望在jsp页面中出现java逻辑代码&#xff0c;同时也由于自定义标签的开发难度较大和不利于技术标准化…

JavaEE程序员必读图书大推荐 .

下面是我根据多年的阅读和实践经验&#xff0c;给您推荐的一些图书&#xff1a; 第一部分&#xff1a; Java语言篇 1 《Java编程规范》 星级&#xff1a; 适合对象&#xff1a;初级&#xff0c;中级 介绍&#xff1a;作者James Gosling&#xff08;Java之父&#xff09;&#x…

10 个深恶痛绝的 Java 异常。。

异常是 Java 程序中经常遇到的问题&#xff0c;我想每一个 Java 程序员都讨厌异常&#xff0c;一 个异常就是一个 BUG&#xff0c;就要花很多时间来定位异常问题。 什么是异常及异常的分类请看这篇文章&#xff1a;一张图搞清楚 Java 异常机制。今天&#xff0c;栈长来列一下 J…

黑盒测试方法之边界值分析法

边界值分析法 概念需求示例1测试用例分析设计1需求示例2测试用例分析设计2总结概念 很多错误发生在输入或输出范围的边界上,因此针对各种边界情况设置测试用例,可以更有效地发现缺陷。 边界值分析法测试用例设计方法:1)确定边界情况(输入或输出等价类的边界);2)选取正…

leetcode381. Insert Delete GetRandom O(1) - Duplicates allowed

题目要求 Design a data structure that supports all following operations in average O(1) time.Note: Duplicate elements are allowed. insert(val): Inserts an item val to the collection. remove(val): Removes an item val from the collection if present. getRando…

js 判断 是否为android

引用&#xff1a;http://www.oschina.net/code/snippet_163910_6094 [代码] JavaScript判断方法 view source print?1if(navigator.userAgent.match(/Android/i)) {2 // Do something!3 // Redirect to Android-site?4 window.location http://android.davidwalsh.nam…

B - Networking - poj 1287

有一些地方需要铺盖电缆&#xff0c;这些地方两点间的路可能不止一条&#xff0c;需要求出来至少需要多少电缆才能让所有的点都连接起来&#xff0c;当然&#xff0c;间接连接也算。/#include<iostream>#include<cstring>#include<cstdio>#include<queue&…

因果图方法中的基本符号

因果图方法中的基本符号 前言基本符号1、恒等2、非3、或4、与5、互斥6、包含7、唯一8、要求9、屏蔽总结前言 经过了春节假期,我们重新回到工作学习中。在学习因果图法前首先要学习因果图方法中的基本符号,今天我们就先解决这些基本符合。 基本符号 1、恒等 恒等:表示原因与…

BZOJ 2190: [SDOI2008]仪仗队( 欧拉函数 )

假设C君为(0, 0), 则右上方为(n - 1, n - 1). 一个点(x, y) 能被看到的前提是gcd(x, y) 1, 所以 answer ∑ phi(i) * 2 2 - 1 ∑phi(i) * 2 1 ( 1 < i < n ). 2是因为(1, 0), (0, 1) 两个点, -1是因为(1, 1)重复计算了--------------------------------------------…

JavaScript数据结构与算法——字典

1.字典数据结构 在字典中&#xff0c;存储的是【键&#xff0c;值】对&#xff0c;其中键名是用来查询特定元素的。字典和集合很相似&#xff0c;集合以【值&#xff0c;值】的形式存储&#xff0c;字典则是用【键&#xff0c;值】对的形式存储。字典也称作映射。 2.创建字典 f…

ArcObjects编程方法(七):.NET中继承ArcGIS COM类

要符合作为基类的要求&#xff0c;coclass必须满足&#xff1a; 定义为元数据可创建聚合然而在ArcGIS中&#xff0c;ArcGIS COM类不能在.NET环境中作为基类。如果要想方便的创建ArcGIS组件&#xff0c;可以使用ESRI.ArcGIS.ADF.Local程序集中提供的类&#xff0c;这些类是托管类…

黑盒测试方法之因果图法

因果图法 因果图法步骤软件需求示例测试用例分析设计总结因果图法步骤 1)赋标识符。分析软件需求规格说明,找出哪些是原因(即输入条件或输入条件的等价类),哪些是结果(即输出条件),并给每个原因和结果赋予一个标识符; 2)画因果图。分析软件需求规格说明,找出原因与…

Git指南-基础篇

一&#xff0c;Git简介 对于一个刚接触Git的同学来说&#xff0c;Git是一个新鲜的东西&#xff0c;为了对Git有更深的了解&#xff0c;强烈推荐一篇博文&#xff1a;Git与Repo入门 它介绍了版本控制的历史&#xff0c;从原始的版本控制&#xff08;即原型-备份-复制-修改-备份-…

silverlight与javascript交互操作

C#端代码&#xff1a; String text "lenny";string text2 "dou";HtmlPage.Window.Invoke("calledBySL2", new object[] { text, text2 }); Html端代码&#xff1a; function calledBySL2(obj, obj2) { alert("Hello: " obj …

JS异步编程之callback

为什么 JS 是单线程&#xff1f; 众所周知&#xff0c;Javascript 语言的执行环境是"单线程"&#xff08;single thread&#xff09;。 所谓"单线程"&#xff0c;就是指一次只能完成一件任务。如果有多个任务&#xff0c;就必须排队&#xff0c;前面一个任…

黑盒测试之两两组合方法

两两组合方法 概念需求示例测试用例分析设计总结概念 所有测试数据两两配对,每一对数据至少出现一次,这个是两两组合测试的基本原理,两两组合测试也称结对测试(Pairwise Testing)。大部分缺陷是在进行两个变量取值冲突的测试时被发现的,不仅仅是在所有的组合情况下才会被…

用JavaScript获取一个超链接的绝对URL地址

对于Web程序员来说&#xff0c;处理简单的URL格式也许会成为一场噩梦。试想一下&#xff0c;一个网址里有很多组成部分都会影响你对它的解析方法&#xff1a; 是否以/字符开头是否以//开头是否以?号开头是否以#号开头…等等当你想要这个地址的绝对地址时&#xff0c;如何判断处…

Docker学习笔记_安装ActiveMQ

一、实验环境 1、宿主机OS:Win10 64位 2、虚拟机OS:Ubuntu18.04,虚拟机名称&#xff1a;Ubuntu18VM1&#xff0c;虚拟机IP:192.168.8.25 3、操作账号 &#xff1a;Docker 4、在虚拟机上已安装Docker 二、安装 简要步骤&#xff1a; 1.搜索镜像 sudo …

Ubuntu下配置Nginx HTTPS

HTTPS(全称&#xff1a;Hypertext Transfer Protocol over Secure Socket Layer)&#xff0c;是以安全为目标的HTTP通道&#xff0c;简单讲是HTTP的安全版。即HTTP下加入SSL层&#xff0c;HTTPS的安全基础是SSL。 它是一个URI scheme(抽象标识符体系)&#xff0c;句法类同http:…

因0x764fb11c的错误状态_《最强大脑》国际赛王易木又被质疑作弊,因背反答案露出了马脚?...

《最强大脑之燃烧吧大脑》第二季国际赛最后一场&#xff0c;中国战队和国际战队在3V3的团战当中以绝对优胜的姿态拿下了本场比赛。在观众为郑林楷、宋一骜以及王易木的成功感到高兴之际&#xff0c;有部分吃瓜群众跳出来指出&#xff0c;之前因作弊而饱受质疑的王易木此次又有了…

[PyQt4]项目开发中遇到的错误与解决办法

1假如将ui文件py化以后产生的关于界面的类是继承object的ui_dialog&#xff0c;方法是setupui,则在主程序中应&#xff1a; app QtGui.QApplication(sys.argv)dialogQtGui.QWidget()ud Ui_Dialog()ud.setupUi(dialog)dialog.show()sys.exit(app.exec_()) 2自建槽checklog_slo…

判断出栈顺序是否正确(栈的压入、弹出序列)

输入两个整数序列。其中一个序列表示栈的push顺序&#xff0c;判断另一个序列有没有可能是对应的pop顺序。为了简单起见&#xff0c;我们假设push序列的任意两个整数都是不相等的。 比如输入的push序列是1、2、3、4、5&#xff0c;那么4、5、3、2、1就有可能是一个pop系列。因为…

LeetCode-135-Candy

算法描述&#xff1a; There are N children standing in a line. Each child is assigned a rating value. You are giving candies to these children subjected to the following requirements: Each child must have at least one candy.Children with a higher rating get…