题目大意:

  传送门

  给两个数列${B_i}、{C_i}$,长度均为$n$,且${B_i}$循环移位线性无关,即不存在一组系数${X_i}$使得对于所有的$k$均有$\sum_{i=0}^{n-1} X_i  B_{k-i \mod n} =0$。

  已知$C$是由$B$与$A$构造得到:

   (搬原图)。

  求所有合法的$A$序列。

题解:

  首先把式子稍加化简会得到:

  显然是个差分式,然后就会得到以下两种结果(以下$B_{i}$均为$B_{i\mod n}$):

    

  问题是,这两个式子都是对的吗?

  显然不是。

  我们考虑题目中说的${B_i}$为循环移位线性无关,但是$\Delta B_i=B_{i+1}-B_{i}$构成的${\Delta B_{i}}$我们是不知道它是否是线性无关的,如果是线性无关,那么它是正确的,反之,我们会知道必然存在一组${X_i}$使得若${A}$有解,则有无穷解,但是回带是错误的。

  但是二式我们如果可以求解可知$\Delta A_i=A_{i+1}-A{i}$是有唯一解的,然后考虑回带求$A_0$我们就可以得到最多两个解。

  所以本题就变成了求:

   

  设$B'_i=B_{-i}$,即:

    

  即,问题变为求出$\Delta C$的点值然后除去$B'_{*Z/n}$的点值再除去$-2$我们再由$\Delta A$的点值求出其系数即可。

  当然,我们可以知道$\Delta A$的系数小于$2e3$,所以我们防止卡精使用$NTT$。

  由于并不知道$B'_{*Z/n}$的长度,所以不能裸上,需要使用Bluestein's Algorithm。

  这个东西网上几乎没有讲解,好像毛爷爷的《再探》里面有说?

  具体就是:

  

  这样就可以使用一次卷积来求$B'$的点值了。($NTT$并不能直接拆成上面的形式,因为数论变换是没法消去下面除的那个2)

  所以将$ik$变为然后拆解即可。

代码:

  1. #include "bits/stdc++.h"
  2.  
  3. typedef long long ll;
  4.  
  5. inline int read() {
  6. int s=,k=;char ch=getchar();
  7. while (ch<''|ch>'') ch=='-'?k=-:,ch=getchar();
  8. while (ch>&ch<='') s=s*+(ch^),ch=getchar();
  9. return s*k;
  10. }
  11.  
  12. const int N=6e5+;
  13.  
  14. ll mod,g,w[][N],W[][N];
  15.  
  16. inline ll Mult ( ll a,ll b ) {
  17. return ( a*b - (ll)( (long double) a*b/mod )*mod + mod )% mod;
  18. }
  19.  
  20. inline ll powmod ( ll a, ll b ) {
  21. ll ret=;
  22. while (b) {
  23. if (b&) ret=Mult ( ret, a );
  24. b>>=,a=Mult ( a, a);
  25. }return ret;
  26. }
  27.  
  28. inline ll gcd ( ll a,ll b ) { return b?gcd(b,a%b) : a; }
  29.  
  30. int n,m;
  31.  
  32. inline void Get_mod () {
  33. for (m=; (m<=*n) ;m<<= );
  34. ll lcm =1ll* n*m /gcd (n,m);
  35. mod = lcm + ;
  36. while ( mod < 1e5 ) mod += lcm;
  37. while () {
  38. int flag=true;
  39. for (int i=;1ll*i*i<=mod;++i) if (mod%i==) {flag=false;break;}
  40. if (flag) break;
  41. mod+=lcm;
  42. }
  43. for (g=;;++g) {
  44. int flag=true;
  45. for (int i=;1ll*i*i<=mod;++i) if ((mod-)%i==){
  46. if (powmod(g,i)==) {flag=false;break;}
  47. if (powmod(g,(mod-)/i)==) {flag=false;break;}
  48. }
  49. if (flag) break;
  50. }
  51. }
  52.  
  53. inline void Get_wn(){
  54. ll w0=powmod(g,(mod-)/m);
  55. w[][]=w[][]=;
  56. int i;
  57. for (i=;i<m;++i) w[][i]=Mult(w[][i-],w0);
  58. for (i=;i<m;++i) w[][i]=w[][m-i];
  59. w0=powmod(g,(mod-)/n);
  60. W[][]=W[][]=;
  61. for (i=;i<n;++i) W[][i]=Mult(W[][i-],w0);
  62. for (i=;i<n;++i) W[][i]=W[][n-i];
  63. }
  64.  
  65. inline void NTT(ll *a,int n,int f) {
  66. register int i,j,k,l,t;
  67. for (i=j=;i^n;++i) {
  68. if (i>j) std::swap(a[i],a[j]);
  69. for (k=n>>;(j^=k)<k;k>>=);
  70. }
  71. for (i=;i<n;i<<=)
  72. for (j=,t=n/(i<<);j<n;j+=i<<)
  73. for (k=l=;k<i;++k , l+=t ) {
  74. ll x=a[j+k],y=Mult(a[i+j+k],w[f][l]);
  75. a[j+k]=x+y;
  76. a[i+j+k]=x-y;
  77. if (a[j+k]>=mod) a[j+k]-=mod;
  78. if (a[i+j+k]<) a[i+j+k]+=mod;
  79. }
  80. if (f ) {
  81. ll rev=powmod ( n,mod- );
  82. for (i=;i<n;++i) a[i]=Mult(a[i],rev);
  83. }
  84. }
  85.  
  86. ll Y[N];
  87.  
  88. inline void pre_Bluestein(int f) {
  89. int i;
  90. for (i=;i<*n;++i) Y[*n--i]=W[f][1ll*i*(i-)/%n];
  91. for (i=*n;i<m;++i) Y[i]=;
  92. NTT(Y,m,);
  93. }
  94.  
  95. inline void Bluestein(ll *a,int f){
  96. static ll X[N];
  97. register int i;
  98. for (i=;i<n;++i) X[i]=Mult(a[i],W[f][ (n-1ll*i*(i-)/%n)%n ]);
  99. for (i=n;i<m;++i) X[i]=;
  100. NTT(X,m,);
  101. for (i=;i<m;++i) X[i]=Mult(X[i],Y[i]);
  102. NTT(X,m,);
  103. for (i=;i<n;++i)
  104. a[i]=Mult (X[*n--i],W[f][(n-1ll*i*(i-)/%n)%n ]);
  105. if (f) {
  106. ll rev=powmod(n,mod-);
  107. for (i=;i<n;++i) a[i]=Mult(a[i],rev);
  108. }
  109. }
  110.  
  111. int b[N],c[N];
  112. ll rev_b[N],delta_c[N],delta_a[N],a[N];
  113.  
  114. int main() {
  115. //freopen(".in","r",stdin);
  116. n = read();
  117. register int i;
  118. for (i=;i<n;++i) b[i]=read();
  119. for (i=;i<n;++i) c[i]=read();
  120. Get_mod();
  121. Get_wn();
  122. for (i=;i<n;++i) rev_b[i]=b[i];
  123. std::reverse(rev_b+,rev_b+n);
  124. ll inv_2=powmod(mod-,mod-);
  125. for (i=;i<n;++i) delta_c[i]=Mult ( ( c[(i+)%n]-c[i] + mod )%mod , inv_2 );
  126. pre_Bluestein();
  127. Bluestein(rev_b,);
  128. Bluestein(delta_c,);
  129. for (i=;i<n;++i) delta_a[i]=Mult ( delta_c[i] , powmod (rev_b[i],mod-) );
  130. pre_Bluestein();
  131. Bluestein(delta_a,);
  132. for (i=;i<n;++i) {
  133. ll v=(delta_a[i]<mod-delta_a[i])?delta_a[i]:delta_a[i]-mod;
  134. if (abs(v)>) return puts(""),;
  135. a[i]=v;
  136. }
  137. ll _c=-c[],_a=,_b=,sum=;
  138. for (i=;i<n;++i) {
  139. ++_a;
  140. _b+=*(sum-b[i]);
  141. _c+=(sum-b[i])*(sum-b[i]);
  142. sum+=a[i];
  143. }
  144. if (sum!=) {
  145. puts("");
  146. return ;
  147. }
  148. std::set<ll> ans;
  149. if (_b*_b-*_a*_c>=){
  150. ll s=ll(sqrt(_b*_b-*_a*_c) + 0.5);
  151. if (s*s!=_b*_b-*_a*_c) return puts(""),;
  152. if ((-_b+s)%(*_a)==) ans.insert((-_b+s)/(*_a));
  153. if ((-_b-s)%(*_a)==) ans.insert((-_b-s)/(*_a));
  154. }
  155. std::set<ll>::iterator it;
  156. printf("%d\n",ans.size());
  157. for (it=ans.begin();it!=ans.end();++it) {
  158. ll now=*it;
  159. for (i=;i<n;++i){
  160. printf("%lld ",now);
  161. now+=a[i];
  162. }
  163. puts("");
  164. }
  165. }

codeforces901E

[codeforces 901E] Cyclic Cipher 循环卷积-Bluestein's Algorithm的更多相关文章

  1. codeforces 722F - Cyclic Cipher

    题目链接:http://codeforces.com/problemset/problem/722/F ------------------------------------------------ ...

  2. Bluestein's Algorithm

    网上很少有人提到,写的也很简单,事实上就是很简单... \(Bluestein's\ Algorithm\),用以解决任意长度\(DFT\). 考虑\(DFT\)的形式:\[\begin{aligne ...

  3. CodeForces - 156C:Cipher (不错的DP)

    Sherlock Holmes found a mysterious correspondence of two VIPs and made up his mind to read it. But t ...

  4. Codeforces - 102222C - Caesar Cipher

    https://codeforc.es/gym/102222/my 好像在哪里见过这个东西?字符的左右移还是小心,注意在mod26范围内. #include<bits/stdc++.h> ...

  5. codeforces 708ALetter Cyclic Shift

    2019-05-18 09:51:19 加油,加油,fightting !!! https://www.cnblogs.com/ECJTUACM-873284962/p/6375011.html 全为 ...

  6. 再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Bluestein算法+分治FFT+FFT的优化+任意模数NTT)

    再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Bluestein算法+分治FFT+FFT的优化+任意模数NTT) 目录 再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Blueste ...

  7. Codeforces Round #453 (Div. 1)

    Codeforces Round #453 (Div. 1) A. Hashing Trees 题目描述:给出一棵树的高度和每一层的节点数,问是否有两棵树都满足这个条件,若有,则输出这两棵树,否则输出 ...

  8. Codeforces Round #453

    Visiting a Friend Solution Coloring a Tree 自顶向下 Solution Hashing Trees 连续2层节点数都超过1时能异构 Solution GCD ...

  9. 【Codeforces 1083C】Max Mex(线段树 & LCA)

    Description 给定一颗 \(n\) 个顶点的树,顶点 \(i\) 有点权 \(p_i\).其中 \(p_1,p_2,\cdots, p_n\) 为一个 \(0\sim (n-1)\) 的一个 ...

随机推荐

  1. asp.net mvc控制器激活全分析

    控制器的激活默认情况下使用反射来实现的,这其中采用了DI,单例等设计模式.对于控制器的主要涉及到如下的类:ControllerBuilder.DefaultControllerFactory.Defa ...

  2. Angular v6 正式发布

    Angular 6 正式发布 Angular 6 已经正式发布了!这个主要版本并不关注于底层的框架,更多地关注于工具链,以及使 Angular 在未来更容易快速推进. 作为发布的一部分,我们同步了主要 ...

  3. shell中的crontab定时任务

    一.crontab简介: crond是linux下用来周期性的执行某种任务或等待处理某些事件的一个守护进程,与windows下的计划任务类似,当安装完成操作系统后,默认会安装此服务工具,并且会自动启动 ...

  4. 编码与Python的基础

    编码 在linux 系统或者Python2版本中要用Python这门语言呢,就需要在开头加上 # -*- coding:utf8 -*- 这个语句是说呀,当机器编译你写的程序的时候是用utf-8这种编 ...

  5. java -- 对Map按键排序、按值排序

                             java  -- 对Map按键.按值排序 1.按键排序(sort by key) 直接上代码  ↓ public Map<String, Str ...

  6. classes目录中没有class文件的一个原因

    可能是你的build设置有问题:比如本来有的jar被删除的情况下.build不会报错,但是classes目录下什么都没有.

  7. Commandline OpenVPN client on Mac OSX with macports

    http://www.tuicool.com/articles/FjuyQj  注:文中有些内容做了修改,特别是那个配置文件,不能直接抄着用. Most people use TunnelBrick ...

  8. C#实现的HttpGet请求

    话不多说,代码贴上: /// <summary> /// HTTP Get请求 /// </summary> /// <param name="url" ...

  9. api大全

    免费api大全(更新中) API大全  http://www.apidq.com/    (这个碉堡了) 天气接口 气象局接口 完整数据:http://m.weather.com.cn/data/10 ...

  10. windows系统命令行

    使用   命令+/?就可显示命令的详细说明. 比如   ping/?就可知道ping命令的详细使用说明 netstat /?就可知道ping命令的使用说明