题解

前置技能

1.多项式求逆

求\(f(x)\*g(x) \equiv 1 \pmod {x^{t}}\)

我们在t == 1时,有\(f[0] = frac{1}{g[0]}\)

之后呢,我们倍增一下,假如新的答案是\(g'(x)\)在\(\pmod {x^{2t}}\)意义下,显然有

\(g'(x) - g(x) \equiv 0 \pmod {x^{t}}\)

我们两边平方一下

\(g'^{2}(x) - 2g'(x)g(x) + g^{2}(x) \equiv 0 \pmod {x^{2t}}\)

两边再乘上一个\(f(x)\)

\(g'(x) - 2g(x) + f(x)g^{2}(x) \equiv 0 \pmod {x^{2t}}\)

那么答案就是

\(g'(x) \equiv = g(x)(2 - f(x)g(x))\)

这是我们熟悉的卷积形式,可以直接上FFT

注意指数上界是e * 2因为有三个多项式相乘

2.多项式除法

\(f(x) = g(x)q(x) + r(x)\)

设\(f(x)\)的度数为\(n\),\(g(x)\)的度数为\(m\),\(q(x)\)的度数为\(n - m\)

\(r(x)\)的度数小于等于\(m - 1\)

\(f(\frac{1}{x}) = g(\frac{1}{x})q(\frac{1}{x}) + r(\frac{1}{x})\)

\(x^{n}f(\frac{1}{x}) = x^{n}g(\frac{1}{x})q(\frac{1}{x}) + x^{n}r(\frac{1}{x})\)

设\(R(f)\)为f的每项系数翻转过来

则式子可以变为

\(R(f) = R(g)R(q) + x^{n - m + 1}R(r)\)

再在两边取模\(x^{n - m + 1}\)

则\(R(q) \equiv \frac{R(f)}{R(g)} \pmod {x^{n - m + 1}}\)

3.多项式取模

做完多项式除法后,用减掉商和被除数的乘积

再来看这道题

我们发现,这个式子生成的方式有点难受,我们就把系数翻转过来

我们用指数大小代表是序列的第几项

然后呢,我们发现其实就是如果生成了一个\(x^{k + 1}\)我们要把它分解成那个线性递推式即\(\sum_{i = 1}^{k}a_{i}x^{i}\)

设\(g(x) = x^{k + 1} - \sum_{i = 1}^{k}a_{i}x^{i}\)

答案也就是\(x^{n} \pmod {g(x)}\)的结果

这样只要做多项式快速幂然后取模多项式就好了

代码

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <algorithm>
  5. #include <cmath>
  6. #include <ctime>
  7. #include <vector>
  8. #include <set>
  9. //#define ivorysi
  10. #define eps 1e-8
  11. #define mo 974711
  12. #define pb push_back
  13. #define mp make_pair
  14. #define pii pair<int,int>
  15. #define fi first
  16. #define se second
  17. #define MAXN 30005
  18. using namespace std;
  19. typedef long long int64;
  20. typedef unsigned int u32;
  21. typedef double db;
  22. const int MOD = 25 * (1 << 22) + 1,G = 3,L = (1 << 22);
  23. int W[L + 5],F[MAXN],K;
  24. int64 N;
  25. template<class T>
  26. void read(T &res) {
  27. res = 0;char c = getchar();T f = 1;
  28. while(c < '0' || c > '9') {
  29. if(c == '-') f = -1;
  30. c = getchar();
  31. }
  32. while(c >= '0' && c <= '9') {
  33. res = res * 10 - '0' + c;
  34. c = getchar();
  35. }
  36. }
  37. template<class T>
  38. void out(T x) {
  39. if(x < 0) putchar('-');
  40. while(x >= 10) {
  41. out(x / 10);
  42. }
  43. putchar(x % 10 + '0');
  44. }
  45. int fpow(int x,int c) {
  46. int res = 1,t = x;
  47. while(c) {
  48. if(c & 1) res = 1LL * res * t % MOD;
  49. t = 1LL * t * t % MOD;
  50. c >>= 1;
  51. }
  52. return res;
  53. }
  54. struct poly {
  55. int a[65537],deg;
  56. poly() {
  57. memset(a,0,sizeof(a));
  58. deg = 0;
  59. }
  60. friend void NTT(poly &f,int on,int M) {
  61. for(int i = 1 , j = M / 2 ; i < M - 1 ; ++i) {
  62. if(i < j) swap(f.a[i],f.a[j]);
  63. int k = M / 2;
  64. while(j >= k) {
  65. j -= k;
  66. k >>= 1;
  67. }
  68. j += k;
  69. }
  70. for(int h = 2 ; h <= M ; h <<= 1) {
  71. int wn = W[(L + on * L / h) % L];
  72. for(int k = 0 ; k < M ; k += h) {
  73. int w = 1;
  74. for(int j = k ; j < k + h / 2 ; ++j) {
  75. int u = f.a[j];
  76. int t = 1LL * f.a[j + h / 2] * w % MOD;
  77. f.a[j] = (u + t) % MOD;
  78. f.a[j + h / 2] = (u + MOD - t) % MOD;
  79. w = 1LL * wn * w % MOD;
  80. }
  81. }
  82. }
  83. if(on < 0) {
  84. int Inv = fpow(M,MOD - 2);
  85. for(int i = 0 ; i < M ; ++i) f.a[i] = 1LL * f.a[i] * Inv % MOD;
  86. }
  87. }
  88. friend poly operator + (const poly &f,const poly &g) {
  89. poly h;
  90. int t = max(f.deg,g.deg);
  91. for(int i = 0 ; i <= t ; ++i) {
  92. h.a[i] = (f.a[i] + g.a[i]) % MOD;
  93. }
  94. for(int i = t ; i >= 0 ; --i) {
  95. if(h.a[i] != 0) {h.deg = i;break;}
  96. }
  97. return h;
  98. }
  99. friend poly operator - (const poly &f,const poly &g) {
  100. poly h;
  101. int t = max(f.deg,g.deg);
  102. for(int i = 0 ; i <= t ; ++i) {
  103. h.a[i] = (f.a[i] + MOD - g.a[i]) % MOD;
  104. }
  105. for(int i = t ; i >= 0 ; --i) {
  106. if(h.a[i] != 0) {h.deg = i;break;}
  107. }
  108. return h;
  109. }
  110. friend poly operator * (poly f,poly g) {
  111. int M = 1;while(M <= f.deg + g.deg) M <<= 1;
  112. NTT(f,1,M);NTT(g,1,M);
  113. poly h;
  114. for(int i = 0 ; i < M ; ++i) {
  115. h.a[i] = 1LL * f.a[i] * g.a[i] % MOD;
  116. }
  117. NTT(h,-1,M);
  118. for(int i = M - 1 ; i >= 0 ; --i) {
  119. if(h.a[i] != 0) {
  120. h.deg = i;
  121. break;
  122. }
  123. }
  124. return h;
  125. }
  126. friend void calc_Inverse(const poly &f,poly &g,int e) {
  127. if(e == 1) {
  128. g.a[0] = fpow(f.a[0],MOD - 2);
  129. g.deg = 0;
  130. return;
  131. }
  132. calc_Inverse(f,g,(e + 1) >> 1);
  133. int M = 1;while(M <= g.deg * 2 + e - 1) M <<= 1;
  134. poly t = f;t.deg = e - 1;
  135. for(int i = e ; i < M ; ++i) t.a[i] = 0;
  136. for(int i = g.deg + 1 ; i < M ; ++i) g.a[i] = 0;
  137. NTT(g,1,M);NTT(t,1,M);
  138. for(int i = 0 ; i < M ; ++i) {
  139. g.a[i] = 1LL * g.a[i] * (2 + MOD - 1LL * g.a[i] * t.a[i] % MOD) % MOD;
  140. }
  141. NTT(g,-1,M);
  142. for(int i = e ; i < M ; ++i) g.a[i] = 0;
  143. g.deg = e - 1;
  144. }
  145. friend poly Inverse(const poly &f,int e) {
  146. poly g;
  147. calc_Inverse(f,g,e);
  148. return g;
  149. }
  150. friend poly operator / (const poly &f,const poly &g) {
  151. poly q;
  152. if(f.deg < g.deg) return q;
  153. poly Rf = f,Rg = g;
  154. reverse(Rf.a,Rf.a + Rf.deg + 1);
  155. reverse(Rg.a,Rg.a + Rg.deg + 1);
  156. int t = f.deg - g.deg + 1;
  157. for(int i = t ; i <= Rg.deg ; ++i) Rg.a[i] = 0;
  158. for(int i = t ; i <= Rf.deg ; ++i) Rf.a[i] = 0;
  159. Rf.deg = min(Rf.deg,t - 1);
  160. Rg.deg = min(Rg.deg,t - 1);
  161. poly Rq = Rf * Inverse(Rg,t);
  162. q = Rq;
  163. for(int i = t ; i <= q.deg ; ++i) q.a[i] = 0;
  164. reverse(q.a,q.a + t);
  165. q.deg = t - 1;
  166. return q;
  167. }
  168. friend poly operator % (const poly &f,const poly &g) {
  169. if(f.deg < g.deg) return f;
  170. poly q = f / g;
  171. return f - (g * q);
  172. }
  173. friend poly fpow(const poly &x,int64 c,const poly &Mod) {
  174. poly res,t = x;
  175. res.deg = 0;res.a[0] = 1;
  176. while(c) {
  177. if(c & 1) res = res * t % Mod;
  178. t = t * t % Mod;
  179. c >>= 1;
  180. }
  181. return res;
  182. }
  183. }M,X;
  184. void Init() {
  185. W[0] = 1,W[1] = fpow(G,25);
  186. for(int i = 2 ; i < L ; ++i) W[i] = 1LL * W[i - 1] * W[1] % MOD;
  187. read(K);read(N);
  188. for(int i = 1 ; i <= K ; ++i) read(F[i]);
  189. int a;
  190. M.deg = K + 1;
  191. for(int i = 1 ; i <= K ; ++i) {
  192. read(a);
  193. M.a[K - i + 1]= MOD - a;
  194. }
  195. M.a[K + 1] = 1;
  196. X.deg = 1;X.a[1] = 1;
  197. }
  198. void Solve() {
  199. X = fpow(X,N,M);
  200. int64 ans = 0;
  201. for(int i = 1 ; i <= K ; ++i) {
  202. ans = ans + 1LL * X.a[i] * F[i] % MOD;
  203. }
  204. ans %= MOD;
  205. printf("%lld\n",ans);
  206. }
  207. int main() {
  208. #ifdef ivorysi
  209. freopen("f1.in","r",stdin);
  210. #endif
  211. Init();
  212. Solve();
  213. return 0;
  214. }

【Codechef】Random Number Generator(多项式除法)的更多相关文章

  1. 文献翻译|Design of True Random Number Generator Based on Multi-stage Feedback Ring Oscillator(基于多级反馈环形振荡器的真随机数发生器设计)

    基于多级反馈环形振荡器的真随机数发生器设计 摘要 真随机数生成器(trng)在加密系统中起着重要的作用.本文提出了一种在现场可编程门阵列(FPGA)上生成真随机数的新方法,该方法以 多级反馈环形振荡器 ...

  2. @codechef - RNG@ Random Number Generator

    目录 @description@ @solution@ @part - 1@ @part - 2@ @part - 3@ @accepted code@ @details@ @description@ ...

  3. Random Number Generator

    rand()函数可以产生[0,RAND_MAX]之间的均匀的伪随机数,它定义在头文件stdlib.h中,函数原型: int rand(void); C标准库的实现是: unsigned ; /*ran ...

  4. [spojRNG]Random Number Generator

    先将所有数加上Ri,即变为区间[0,2Ri],考虑容斥,将区间容斥为[0,+oo)-[2Ri,+oo),然后对[2Ri,+oo)令$bi=ai-2Ri$,相当于范围都是[0,+oo)问题转化为求n个正 ...

  5. Random number

    Original #include <stdlib.h> #include <time.h> srand(time(NULL)); rand(); The versions o ...

  6. Case Study: Random Number Generation(翻译教材)

    很荣幸,经过三天的努力.终于把自己翻译的教材做完了,现在把它贴出来,希望能指出其中的不足.   Case Study: Random Number Generation Fig. 6.7  C++ 标 ...

  7. ISO C Random Number Functions

    This section describes the random number functions that are part of the ISO C standard. To use these ...

  8. How to generate a random number in R

    Generate a random number between 5.0 and 7.5x1 <- runif(1, 5.0, 7.5) # 参数1表示产生一个随机数x2 <- runif ...

  9. Linux shell get random number

    the Shell Profile: When a new interactive shell is started, /etc/profile, followed by /etc/bash.bash ...

随机推荐

  1. UIView的alpha属性和hidden属性

    alpha 属性为0.0时视图完全透明,为1.0时视图完全不透明. hidden属性为YES时视图隐藏,否则不隐藏. 注意事项: 1 当视图完全透明或者隐藏时,不能响应触摸消息. 也就是alpha等于 ...

  2. python---django的模块简便使用

    一:登录操作 from django.contrib.auth import authenticate,login,logout #可以用来做登录验证 from django.contrib.auth ...

  3. 跨域ajax请求携带cookie

    通过withCredentials 方式: getCompanySubject: function () { return axios.get(this.apiUrls.getCompanySubje ...

  4. 【精选】Nginx负载均衡学习笔记(一)实现HTTP负载均衡和TCP负载均衡(官方和OpenResty两种负载配置)

    说明:很简单一个在HTTP模块中,而另外一个和HTTP 是并列的Stream模块(Nginx 1.9.0 支持) 一.两个模块的最简单配置如下 1.HTTP负载均衡: http { include m ...

  5. 【精选】Ubuntu 14.04 安装Nginx、php5-fpm、ThinkPHP5.0(已经测试上线)

    sudo apt-get update 安裝Nginx https://www.vultr.com/docs/setup-nginx-rtmp-on-ubuntu-14-04 安裝完成後,Nginx的 ...

  6. Throwable、Error、Exception、RuntimeException 区别

    1.java将所有的错误封装为一个对象,其根本父类为Throwable, Throwable有两个子类:Error和Exception. 2.Error是Throwable 的子类,用于指示合理的应用 ...

  7. 最小生成树 kuangbin专题最后一个题

    题目链接:https://cn.vjudge.net/contest/66965#problem/N 注释:这道题需要用krustra,用prim的话可能会超时.并且在计算距离的时候要尽量减少步骤,具 ...

  8. cmake设置默认静态链接库

    在使用cmake来编写CMakeLists.txt时,如果不特别指明,那么cmake是默认动态链接库的,最终生成的二进制文件只能在与本地相同环境下的机器运行,如果想把生成的二进制拷贝到其他机器上执行, ...

  9. Linux嵌入式交叉编译环境 的搭建【转】

    转自:http://blog.csdn.net/woaixiaozhe/article/details/7395435 1. 安装标准的C开发环境,由于Linux安装默认是不安装的,所以需要先安装一下 ...

  10. Team Foundation Server 2010服务器安装

    本安装指南使用Windows Server 2008企业版为基础,安装Windows Server 2008 SP2(必须),在此操作系统环境上进行TFS2010的安装与配置. 三.系统用户设置 1. ...