Recurrent Function
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 1233   Accepted: 336

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

2
1
1 0
4
7
2
1
0 1
100
200
-1

Sample Output

1
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
 
题意:求解递归方程,该类方程在具体数学第一章中有明确介绍,这里只给结论,若要求解f(x),可以先将x转化成c进制c进制一共m位,即(xmxm-1...x1x0)c,那么有结论:
f((xmxm-1...x1x0)c)=(axmbxm-1bxm-2...bx1bx0)c
思路:结论已介绍,可以看出将x化成c进制后每一位都在进行置换操作,c进制首位用ai来置换,后面几位都用bi来置换。那么如果将k也转化成d进制,那么如果m的d进制的每一位通过不断置换之后最终与k的每一位分别相等,置换的最小次数x就是所求。
我们设最少置换x次,m的d进制的每一位各自置换到k的每一位需要ci次,并且每一位置换足够次数会产生轮回,轮回的大小记为loop(i)
那么x满足条件:
x==c1 mod(loop(1))
x==c2 mod(loop(2))
.....
x==cn mod(loop(n))
这样就是求满足上述模方程组的最小解即可。
 
AC代码:
#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<cstring>
#include<set>
#include<string>
#include<queue>
#include<cmath>
using namespace std;
#define INF 0x3f3f3f3f
const int N_MAX = +;
typedef long long ll;
// 大数类
class bign
{
#define base 1000
#define digit 3
private:
int _arr[];
int _m;
void bign::_simplify(void)
{
for (int i = ; i <= _m; i++)
{
if (i == _m && _arr[i] >= base) _m++;
_arr[i + ] += _arr[i] / base;
_arr[i] %= base;
}
}
public:
bign::bign(void) : _m() { memset(_arr, , sizeof(_arr)); }
bign::bign(int init) : _m()
{
memset(_arr, , sizeof(_arr));
_arr[] = init;
_simplify();
}
friend istream& operator >> (istream& fin, bign& a)
{
char init[]; int len, b, t;
fin >> init;
len = strlen(init); a._m = -;
for (int i = len - ; i >= ;)
{
t = , b = ;
for (int j = ; j < digit && i >= ; j++, i--)
{
t += (init[i] - '') * b;
b *= ;
}
a._arr[++a._m] = t;
}
return fin;
}
friend bign operator / (bign a, int b)
{
for (int i = a._m; i >= ; i--)
{
if (a._arr[i] < b && i == a._m && i != ) a._m--;
if (i > ) a._arr[i - ] += (a._arr[i] % b) * base;
a._arr[i] /= b;
} return a;
}
friend int operator % (bign a, int b)
{
for (int i = a._m; i >= ; i--)
{
if (i == ) return a._arr[i] % b;
else a._arr[i - ] += (a._arr[i] % b) * base;
}
}
friend bool operator == (bign a, bign b)
{
if (a._m != b._m) return false;
for (int i = ; i <= a._m; i++)
if (a._arr[i] != b._arr[i]) return false;
return true;
}
}; pair<ll,ll> trans(ll *a,ll m,ll k ) {//采用a置换,m为需要置换的数,k为m置换的终点,返回循环次和圈的大小
ll num = ;//num为从m到k的循环次数,不存在则为-1
ll tmp = m;
while (tmp!=k) {
if (num != && tmp == m) { num = -; break; }
num++;
tmp = a[tmp];
}
if (num == -)return make_pair(-, );
int loop = ;
while () {
if (loop != && tmp == k) { break; }
loop++;
tmp = a[tmp];
}
return make_pair(num,loop);
} ll gcd(ll a,ll b) {
if (b == )return a;
return gcd(b, a%b);
} ll extgcd(ll a,ll b,ll &x,ll &y) {
if (b == ) {
x = ; y = ;
return a;
}
ll ans = extgcd(b,a%b,x,y);
ll tmp = x;
x = y;
y = tmp - a / b*y;
return ans;
}
ll mod_inverse(ll a,ll m) {
ll x, y;
extgcd(a,m,x,y);
return (m + x%m) % m;
} pair<ll, ll>linear_congruence(const ll *A,const ll *B,const ll*M,const int& num) {
ll x = ,m = ;
for (int i = ; i < num;i++) {
ll a = A[i] * m, b = B[i] - A[i] * x, d = gcd(M[i], a);
if (b%d != )return make_pair(, -);
ll t = b / d*mod_inverse(a / d, M[i] / d) % (M[i] / d);
x = x + m*t;
m *= M[i] / d;
}
return make_pair((x%m+m)%m, m);
} ll d;
ll a[N_MAX], b[N_MAX];
bign k, m;
ll kd[N_MAX], md[N_MAX];//存储k和m的D进制形式
ll A[N_MAX], B[N_MAX], M[N_MAX];
int main() {
while(scanf("%lld",&d)&&d!=-) {
for (int i = ; i < d;i++)scanf("%lld",&a[i]);
for (int i = ; i < d;i++)scanf("%lld",&b[i]);
cin >> m >> k;
int num = ;
while (!(m==)) {
md[num++] = m%d;
m =m/ d;
}
int num2 = ;
while (!(k == )) {
kd[num2++] = k%d;
k = k / d;
}
if (num != num2) { puts("NO"); continue; }
pair<ll, ll>P;
bool flag = ;
for (int i = ; i < num-;i++) {
P = trans(b,md[i],kd[i]);
if (P.first == -) { puts("NO"); flag = ; break; }
A[i] = , B[i] = P.first, M[i] = P.second;
}
if (flag)continue; P = trans(a, md[num - ], kd[num - ]);
if (P.first == -) { puts("NO"); continue; }
A[num - ] = , B[num - ] = P.first, M[num - ] = P.second;
P = linear_congruence(A,B,M,num);
if(P.second==-) { puts("NO"); continue; }
else printf("%lld\n",P.first);
}
return ;
}

poj 3708 Recurrent Function的更多相关文章

  1. [转] POJ数学问题

    转自:http://blog.sina.com.cn/s/blog_6635898a0100magq.html 1.burnside定理,polya计数法 这个大家可以看brudildi的<组合 ...

  2. acm数学(转)

    这个东西先放在这吧.做过的以后会用#号标示出来 1.burnside定理,polya计数法    这个大家可以看brudildi的<组合数学>,那本书的这一章写的很详细也很容易理解.最好能 ...

  3. ACM数学

     1.burnside定理,polya计数法 这个专题我单独写了个小结,大家可以简单参考一下:polya 计数法,burnside定理小结 2.置换,置换的运算 置换的概念还是比较好理解的,< ...

  4. (转) Written Memories: Understanding, Deriving and Extending the LSTM

    R2RT   Written Memories: Understanding, Deriving and Extending the LSTM Tue 26 July 2016 When I was ...

  5. 从rnn到lstm,再到seq2seq(一)

    rnn的的公式很简单: 对于每个时刻,输入上一个时刻的隐层s和这个时刻的文本x,然后输出这个时刻的隐层s.对于输出的隐层s 做个ws+b就是这个时刻的输出y. tf.scan(fn, elems, i ...

  6. poj3708(公式化简+大数进制装换+线性同余方程组)

    刚看到这个题目,有点被吓到,毕竟自己这么弱. 分析了很久,然后发现m,k都可以唯一的用d进制表示.也就是用一个ai,和很多个bi唯一构成. 这点就是解题的关键了. 之后可以发现每次调用函数f(x),相 ...

  7. ACM数学知识体系

    在盛情收到学弟邀请给他们整理ACM数学方面的知识体系,作为学长非常认真的弄了好久,希望各学弟不辜负学长厚爱!!!非常抱歉因为电脑全盘格式化好多word.PPT都丢失,我尽量具体地给大家找到各知识点学习 ...

  8. Image Captioning 经典论文合辑

    Image Caption: Automatically describing the content of an image domain:CV+NLP Category:(by myself, y ...

  9. 通过百度echarts实现数据图表展示功能

    现在我们在工作中,在开发中都会或多或少的用到图表统计数据显示给用户.通过图表可以很直观的,直接的将数据呈现出来.这里我就介绍说一下利用百度开源的echarts图表技术实现的具体功能. 1.对于不太理解 ...

随机推荐

  1. java基础—基础语法2

    一.语句

  2. 阿里云服务器下安装LAMP环境(CentOS Linux 6.3)

    http://ninghao.net/course/514 http://www.sphinxsearch.org/archives/243 ctrl + l  putty 清理屏幕 apache 自 ...

  3. 【转】再谈 最速下降法/梯度法/Steepest Descent

    转载请注明出处:http://www.codelast.com/ 最速下降法(又称梯度法,或Steepest Descent),是无约束最优化领域中最简单的算法,单独就这种算法来看,属于早就“过时”了 ...

  4. linux centos 下ssh的连接

    参考链接 虚拟机下CentOS7开启SSH连接 记录 我用finalssh连接virtualbox里的centos,发现报出java.net.UnknownHostException 一开始我以为是s ...

  5. How To Add Swap Space on Ubuntu 16.04

    Introduction One of the easiest way of increasing the responsiveness of your server and guarding aga ...

  6. CentOS 6 搭建SVN支持httpd和svnserve独立服务器两种模式 以及邮件配置

    Linux下SVN服务器同时支持Apache的http和svnserve独立服务器两种模式且使用相同的访问权限账号 服务器操作系统:CentOS 6.x 1.在服务器上安装配置SVN服务: 2.配置S ...

  7. 通过composer安装阿里大于接口扩展

    # 安装laravel阿里大鱼服务 composer require iscms/alisms-for-laravel laravel配置 # 注册服务 # 在config\app.php文件中找到P ...

  8. 无需上传附件到服务器,Servlet读取Excel(二)

    package com.str; import java.io.File;import java.io.FileInputStream;import java.io.IOException; impo ...

  9. Altium Designer入门学习笔记3:关于各模块分开布线的理解( 1)

    观看"杜洋AD的讲解视频",杜洋着重强调了"模块分开"布线的好处. ---------------------------------------------- ...

  10. nrf528xx bootloader 模块介绍(转载)

    转载https://www.cnblogs.com/rfnets/p/8205521.html 1. bootloader 的基本功能: 启动应用 几个应用之间切换 初始化外设 nordic nrf5 ...