刚看到这个题目,有点被吓到,毕竟自己这么弱。

分析了很久,然后发现m,k都可以唯一的用d进制表示。也就是用一个ai,和很多个bi唯一构成。

这点就是解题的关键了。 之后可以发现每次调用函数f(x),相当于a(ai),b(bi)了一下。这样根据置换的一定知识,一定会出现循环,而把循环的大小看成取模,把从m->k的看成余,于是可以建立一个线性同余方程。

直接用模板解决之。。

Recurrent Function
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 1102   Accepted: 294

Description

Dr. Yao is involved in a secret research on the topic of the properties of recurrent function. Some of the functions in this research are in the following pattern:

in which set {ai} = {1, 2, …, d-1} and {bi} = {0, 1, …, d-1}.
We denote:

Yao's question is that, given two positive integer m and k, could you find a minimal non-negative integer x that

Input

There are several test cases. The first line of each test case contains an integer d (2≤d≤100). The second line contains 2d-1 integers: a1, …, ad-1, followed by b0, ..., bd-1. The third line contains integer m (0<m≤10100), and the forth line contains integer k (0<k≤10100). The input file ends with integer -1. 

Output

For each test case if it exists such an integer x, output the minimal one. We guarantee the answer is less than 263. Otherwise output a word "NO". 

Sample Input

  1. 2
  2. 1
  3. 1 0
  4. 4
  5. 7
  6. 2
  7. 1
  8. 0 1
  9. 100
  10. 200
  11. -1

Sample Output

  1. 1
  2. NO

Hint

For the first sample case, we can see that f(4)=7. And for the second one, the function is f(i)=i
  1. //
  2. // main.cpp
  3. // poj3708
  4. //
  5. // Created by 陈加寿 on 15/11/28.
  6. // Copyright (c) 2015年 陈加寿. All rights reserved.
  7. //
  8.  
  9. #include <iostream>
  10. #include <stdio.h>
  11. #include <string.h>
  12. #include <algorithm>
  13. #include <math.h>
  14. using namespace std;
  15.  
  16. int a[],b[];
  17. char strm[],strk[];
  18. int m[],k[];
  19. int savem[],savek[];
  20. int cntm,cntk;
  21.  
  22. void Tentod(int ten[],int len,int &cnt,int d,int save[])
  23. {
  24. int tcnt=;
  25. while(ten[tcnt]==) tcnt++;
  26. cnt=;
  27. while(tcnt<len)
  28. {
  29. for(int i=tcnt;i<len;i++)
  30. {
  31. ten[i+] += (ten[i]%d)*;
  32. ten[i] /= d;
  33. }
  34. save[cnt++] = ten[len]/;
  35. ten[len]=;
  36. while(tcnt<len&&ten[tcnt]==) tcnt++;
  37. }
  38. /*
  39. for(int i=0;i<cnt;i++)
  40. printf("%d ",save[i]);
  41. printf("\n");
  42. */
  43. }
  44.  
  45. /*对于x=r0(mod m0)
  46. x=r1(mod m1)
  47. ...
  48. x=rn(mod mn)
  49. 输入数组m和数组r,返回[0,[m0,m1,...,mn]-1] 范围内满足以上等式的x0。
  50. x的所有解为:x0+z*[m0,m1,...mn](z为整数)
  51. */
  52. long long cal_axb(long long a,long long b,long long mod)
  53. {
  54. //防乘法溢出
  55. long long sum=;
  56. while(b)
  57. {
  58. if(b&) sum=(sum+a)%mod;
  59. b>>=;
  60. a=(a+a)%mod;
  61. }
  62. return sum;
  63. }
  64.  
  65. //ax + by = gcd(a,b)
  66. //传入固定值a,b.放回 d=gcd(a,b), x , y
  67. void extendgcd(long long a,long long b,long long &d,long long &x,long long &y)
  68. {
  69. if(b==){d=a;x=;y=;return;}
  70. extendgcd(b,a%b,d,y,x);
  71. y -= x*(a/b);
  72. }
  73.  
  74. long long Multi_ModX(long long m[],long long r[],int n)
  75. {
  76. long long m0,r0;
  77. m0=m[]; r0=r[];
  78. for(int i=;i<n;i++)
  79. {
  80. long long m1=m[i],r1=r[i];
  81. long long k0,k1;
  82. long long tmpd;
  83. extendgcd(m0,m1,tmpd,k0,k1);
  84. if( (r1 - r0)%tmpd!= ) return -;
  85. k0 *= (r1-r0)/tmpd;
  86. m1 *= m0/tmpd;
  87. r0 = ( cal_axb(k0,m0,m1)+r0)%m1;
  88. m0=m1;
  89. }
  90. return (r0%m0+m0)%m0;
  91. }
  92.  
  93. int main(int argc, const char * argv[]) {
  94. int d;
  95. while(cin>>d)
  96. {
  97. if(d==-) break;
  98. for(int i=;i<d;i++) cin>>a[i];
  99. for(int i=;i<d;i++) cin>>b[i];
  100. scanf("%s",strm);
  101. scanf("%s",strk);
  102. int len = strlen(strm);
  103. for(int i=;i<len;i++)
  104. m[i] = strm[i]-'';
  105. Tentod(m,len,cntm,d,savem);
  106. len = strlen(strk);
  107. for(int i=;i<len;i++)
  108. k[i] = strk[i]-'';
  109. Tentod(k, len, cntk, d, savek);
  110. // 这样就得到了。a,b。。。
  111. // 然后构建同模方程
  112. if(cntm != cntk)
  113. {
  114. printf("NO\n");
  115. }
  116. else
  117. {
  118. int flag=;
  119. long long m[],r[];
  120. for(int i=;i<cntm-;i++)
  121. {
  122. int a1=savem[i],a2=savek[i];
  123. int tm=;
  124. int ta=a1;
  125. while(b[ta]!=a1)
  126. {
  127. tm++;
  128. ta=b[ta];
  129. }
  130. ta=a1;
  131. int tr=;
  132. while(ta != a2)
  133. {
  134. tr++;
  135. ta=b[ta];
  136. if(ta==a1)
  137. {
  138. flag=;
  139. break;
  140. }
  141. }
  142. m[i]=tm;
  143. r[i]=tr;
  144. if(flag==) break;
  145. }//这里面都是b
  146. int a1=savem[cntm-],a2=savek[cntm-];
  147. int tm=;
  148. int ta=a1;
  149. while(a[ta]!=a1)
  150. {
  151. tm++;
  152. ta=a[ta];
  153. }
  154. ta=a1;
  155. int tr=;
  156. while(ta != a2)
  157. {
  158. tr++;
  159. ta=a[ta];
  160. if(ta==a1)
  161. {
  162. flag=;
  163. break;
  164. }
  165. }
  166. m[cntm-]=tm;
  167. r[cntm-]=tr;
  168. if(flag == )
  169. {
  170. printf("NO\n");
  171. }
  172. else
  173. {
  174. long long ans=Multi_ModX(m, r,cntm);
  175. if(ans==-) printf("NO\n");
  176. else cout<<ans<<endl;
  177. }
  178. }
  179. }
  180. return ;
  181. }

poj3708(公式化简+大数进制装换+线性同余方程组)的更多相关文章

  1. poj3708:函数式化简+高精度进制转换+同余方程组

    题目大意 给定一个函数 找出满足条件   等于 k 的最小的x m,k,d已知 其中 m,k 很大需要使用高精度存储 思路: 对 函数f(m)进行化简 ,令t=ceil( log(d,m) ) 可以得 ...

  2. POJ1220(大数进制转换)

    NUMBER BASE CONVERSION Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 4652   Accepted: ...

  3. 洛谷p1017 进制转换(2000noip提高组)

    洛谷P1017 进制转换 题意分析 给出一个数n,要求用负R进制显示. n∈[-32768,32767].R ∈[-20,-2] 考察的是负进制数的转换,需要理解短除法. 看到这道题的时候,我是比较蒙 ...

  4. 洛谷 1017 进制转换 (NOIp2000提高组T1)

    [题解] 纯模拟题. 我们都知道十进制数化成m进制数可以用短除法,即除m取余.逆序排列.而m进制数化为十进制数,按权展开求和即可. 但在本题中进制的基数R可能为负数,我们知道a%R的符号与R一致,也就 ...

  5. 大数进制转换 poj1220

    普通的做法,大数除小数. 复杂度o( log(n)*log(n) ),其实就是位数的平方. NUMBER BASE CONVERSION Time Limit: 1000MS   Memory Lim ...

  6. hdu-1877(大数+进制转换)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1877 思路:注意考虑0,0的情况. #include<iostream> #include ...

  7. 1030 大数进制转换(51Nod + JAVA)

    题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1030 题目: 代码实现如下: import java.mat ...

  8. delphi -- 进制转换 函数表

    1.16 TO 10 ******************************************************** 16转10,否则输出-1 function Hex(c: cha ...

  9. java中的进制转换方法

    java中进行二进制,八进制,十六进制,十进制间进行相互转换 关键字: java 进制转换 十进制转成十六进制: Integer.toHexString(int i) 十进制转成八进制 Integer ...

随机推荐

  1. django自定义过滤器及模板标签

    创建一个模板库 不管是写自定义标签还是过滤器,第一件要做的事是创建模板库(Django能够导入的基本结构). 创建一个模板库分两步走: 第一,决定模板库应该放在哪个Django应用下. 如果你通过 m ...

  2. Oracle数据库实现获取前几条数据的方法

    如何在Oracle数据库中实现获取前几条数据的方法呢?就是类似SQL语句中的SELECT TOP N的方法.本文将告诉您答案,举例说明了哟!   1.在Oracle中实现SELECT TOP N : ...

  3. 网页计算器 && 简易网页时钟 && 倒计时时钟

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  4. 有效的web安全信息源

    杂志:hackcto ,书安 乌云知识库,91ri.org,安全脉搏(http://www.secpulse.com/) 乌云公开漏洞,乌云热点漏洞,90sec 内网渗透找90.web注入找习科, 已 ...

  5. ios网络学习------10 原生API文件上传

    使用原生态的api上传文件的实现: #import "MainViewController.h" @interface MainViewController () @propert ...

  6. Android蓝牙

    代码地址如下:http://www.demodashi.com/demo/12772.html 前言:最近,新换了一家公司,公司的软件需要通过蓝牙与硬件进行通讯,于是趁此机会将Android蓝牙详细的 ...

  7. Java Learning Path(五)资源篇

    Java Learning Path(五)资源篇 1. http://java.sun.com/ (英文) Sun的Java网站,是一个应该经常去看的地方.不用多说. 2.http://www-900 ...

  8. iOS端App的icon和Launch Image规格实时更新

    启动影像 : iPhone :320 x 480 640 x 960 640*1136 750*1334 1242*2208  iPad :768 x 1004 1536 x 2008 APP图标: ...

  9. 网络相关系列之四:数据解析之SAX方式解析XML数据

    一.XML和Json数据的引入: 通常情况下.每一个须要訪问网络的应用程序都会有一个自己的server.我们能够向server提交数据,也能够从server获取数据.只是这个时候就有一个问题,这些数据 ...

  10. NHibernate 组件基础 (第六篇)

    NHibernate 组件基础 (第六篇) 一.组件简介 组件(Component)可以理解为被一个对象所包含的对象而持久化,而并非一个实体.简单说来,假如数据库有FirstName,LastName ...