BZOJ上数据范围没写清楚,实际数据范围如这个表格所示。


把$M_n$和$x$看成$\mathbb{F}_2$下的$m$维的列向量,则有转移矩阵 $$A = \begin{pmatrix} 0 & 0 & \cdots & 0 & -x_0\\ 1 & 0 & \cdots & 0 & -x_1\\ 0 & 1 & \cdots & 0 & -x_2\\ \vdots & \vdots & \ddots & \vdots & \vdots\\ 0 & 0 & \cdots & 1 & -x_{m-1}\\ \end{pmatrix}$$ 该矩阵为多项式 $$p(z) = z^m+\sum_{i=0}^{m-1}x_iz^i$$ 的友阵。因此,若把$M_n$看成$F$中的元素,则有 $$M_n(z) = z^nM_0(z)$$ 其中$F = \mathbb{F}_2[z]/(p(z))$为模$p(z)$意义下的$\mathbb{F}_2$上的多项式构成的环。当然,也可以直接通过观察得出这个结论。注意到$n < m$时$F$中的$z^n$与$\mathbb{F}_2[z]$中的相同,于是可以以复杂度 $$O\bigl(m\log m\max(1,\log k-\log m)\bigr)$$ 解决第一种情况。

所有$2^m-1$个非零元素都能被生成,是数列在这些元素中等概率取值的必要条件。该条件成立时有 $$\begin{aligned} 2^m-1 &= |\mathopen{<}z\mathclose{>}M_0(z)| = |\mathopen{<}z\mathclose{>}|\\ &\le |F^\times| \le |F \setminus \{0\}| = 2^m-1 \end{aligned}$$ 其中$F^\times$为$F$中所有有乘法逆元的元素构成的乘法群。由此得$\mathopen{<}z\mathclose{>} = F^\times = F \setminus \{0\}$,那么$F$为大小为$2^m$的有限域,且$\forall f(z) \in F^\times$,有$(f(z))^{2^m} = f(z)$,故 $$\begin{aligned} M_k(z) &= (z^{k \cdot 2^l})^{2^{m-l}}M_0(z)\\ &= \Bigl(M_{k \cdot 2^l}(z)\bigl(M_0(z)\bigr)^{-1}\Bigr)^{2^{m-l}}M_0(z)\\ &= \bigl(M_{k \cdot 2^l}(z)\bigr)^{2^{m-l}}\Bigl(\bigl(M_0(z)\bigr)^{2^{m-l}}\Bigr)^{2^l-1}\\ \end{aligned}$$ 从而可以以复杂度$O(m^2\log m)$解决第二种情况。

由上述推导可知,$x$是好的等价于$F$是一个域,且$z$是$F^\times$的生成元。$F$是一个域当且仅当$p(z)$是$\mathbb{F}_2$上的既约多项式。由此,或许可以用某些方法生成第二种情况的数据。


这题挺好写的,就一多项式除法就没了,不知道为啥没几个人写。

#include<algorithm>
#include<vector>
#include<cstdio>
#define RAN(a)a.begin(),a.end()
using namespace std;
typedef unsigned long long u64;
typedef unsigned u32;
namespace num{
const u32 p=1811939329;
const u32 g=13;
inline u32 imod(u32 a){
return a<p?a:a-p;
}
inline u32 ipow(u32 a,u32 n){
u32 s=1;
for(;n;n>>=1){
if(n&1)
s=(u64)s*a%p;
a=(u64)a*a%p;
}
return s;
}
inline u32 inv(u32 a){
return ipow(a,p-2);
}
}
using namespace num;
class poly_base{
public:
vector<u32>a;
poly_base(){}
explicit poly_base(int n):a(n){}
void fft(int n,bool f){
a.resize(n);
if(n<=1)
return;
for(int i=0,j=0;i<n;++i){
if(i<j)
std::swap(a[i],a[j]);
int k=n>>1;
while((j^=k)<k)
k>>=1;
}
vector<u32>w(n/2);
w[0]=1;
for(int i=1;i<n;i<<=1){
for(int j=i/2-1;~j;--j)
w[j<<1]=w[j];
int m=(p-1)/i/2;
u64 s=ipow(g,f?p-1-m:m);
for(int j=1;j<i;j+=2)
w[j]=s*w[j-1]%p;
for(int j=0;j<n;j+=i<<1){
u32*b=&a[0]+j,*c=b+i;
for(int k=0;k<i;++k){
u32 v=(u64)w[k]*c[k]%p;
c[k]=imod(b[k]+p-v);
b[k]=imod(b[k]+v);
}
}
}
}
void dft(int n){
fft(n,0);
}
void idft(){
int n=a.size();
fft(n,1);
u64 f=inv(n);
for(int i=0;i<n;++i)
a[i]=f*a[i]%p;
}
};
class poly:public poly_base{
public:
poly(){}
explicit poly(int n):poly_base(n){}
u32&operator[](int i){
return a[i];
}
const u32&operator[](int i)const{
return a[i];
}
int size()const{
return a.size();
}
void swap(poly&b){
a.swap(b.a);
}
static int len(int n){
while(n^n&-n)
n+=n&-n;
return n;
}
void fix(){
while(size()&&!a.back())
a.pop_back();
}
void mul(poly b){
fix();
b.fix();
int n=len(size()+b.size()-1);
dft(n);
b.dft(n);
for(int i=0;i<n;++i)
a[i]=(u64)a[i]*b[i]%p;
idft();
for(int i=0;i<n;++i)
a[i]&=1;
fix();
}
void sqr(){
fix();
int n=len(2*size()-1);
dft(n);
for(int i=0;i<n;++i)
a[i]=(u64)a[i]*a[i]%p;
idft();
for(int i=0;i<n;++i)
a[i]&=1;
fix();
}
void mod(int n){
a.resize(n);
}
void inv(int n){
int m=len(n);
mod(m);
vector<u32>b(1,1);
a.swap(b);
for(int i=2;i<=m;i<<=1){
poly c(i);
for(int j=0;j<i;++j)
c[j]=b[j];
sqr();
mul(c);
mod(i);
}
mod(n);
}
void div(poly b){
fix();
b.fix();
int n=size()-b.size()+1;
if(n<=0){
a.clear();
return;
}
reverse(RAN(a));
mod(n);
reverse(RAN(b.a));
b.inv(n);
mul(b);
mod(n);
reverse(RAN(a));
fix();
}
void mod(poly b){
fix();
b.fix();
int m=b.size();
if(size()>=m){
poly c=*this;
div(b);
mul(b);
mod(m-1);
for(int i=0;i<m-1;++i)
a[i]^=c[i];
fix();
}
}
};
struct ano{
operator u64(){
u64 x=0;
signed c=getchar();
while(c<48)
c=getchar();
while(c>47)
x=x*10+c-48,c=getchar();
return x;
}
}buf;
poly basis(int n){
poly a(n+1);
a[n]=1;
return a;
}
int main(){
int n=buf;
poly p(n+1);
p[n]=1;
for(int i=0;i<n;++i)
p[i]=buf;
poly s(n);
for(int i=0;i<n;++i)
s[i]=buf;
if(buf==0){
u64 k=buf;
if(k<n){
s.mul(basis(k));
s.mod(p);
}else{
int i=0;
while((k&(2<<i)-1)<n)
++i;
s.mul(basis(k&(1<<i)-1));
s.mod(p);
poly a=basis(1<<i);
k>>=i;
for(;k;k>>=1){
if(k&1){
s.mul(a);
s.mod(p);
}
if(k>1){
a.sqr();
a.mod(p);
}
}
}
}else{
int l=buf%n;
poly a(n);
for(int i=0;i<n;++i)
a[i]=buf;
s.swap(a);
for(int i=0;i<n-l;++i){
s.sqr();
s.mod(p);
a.sqr();
a.mod(p);
}
for(int i=0;i<l;++i){
s.mul(a);
s.mod(p);
if(i<l-1){
a.sqr();
a.mod(p);
}
}
}
s.mod(n);
for(int i=0;i<n;++i)
printf("%d",s[i]);
puts("");
}

Rewrited @ 姫野星奏生誕祭2019

Edited @ 2019-06-28

BZOJ3557: [Ctsc2014]随机数的更多相关文章

  1. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  2. .Net使用system.Security.Cryptography.RNGCryptoServiceProvider类与System.Random类生成随机数

    .Net中我们通常使用Random类生成随机数,在一些场景下,我却发现Random生成的随机数并不可靠,在下面的例子中我们通过循环随机生成10个随机数: ; i < ; i++) { Rando ...

  3. DotNet生成随机数的一些方法

    在项目开发中,一般都会使用到“随机数”,但是在DotNet中的随机数并非真正的随机数,可在一些情况下生成重复的数字,现在总结一下在项目中生成随机数的方法. 1.随机布尔值: /// <summa ...

  4. JavaScript 随机数

    JavaScript内置函数random(seed)可以产生[0,1)之间的随机数,若想要生成其它范围的随机数该如何做呢? 生成任意范围的随机数 //生成[100,120)之间的随机数 Math.fl ...

  5. SQL Server 随机数,随机区间,随机抽取数据rand(),floor(),ceiling(),round(),newid()函数等

    在查询分析器中执行:select rand(),可以看到结果会是类似于这样的随机小数:0.36361513486289558,像这样的小数在实际应用中用得不多,一般要取随机数都会取随机整数.那就看下面 ...

  6. 随机数(random)

    需求 Random rd=new Random(); 需要十以内的随机数  (0---10) System.out.println((int)((rd.nextDouble()*100)/10)); ...

  7. BZOJ 3555: [Ctsc2014]企鹅QQ [字符串哈希]【学习笔记】

    3555: [Ctsc2014]企鹅QQ Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 2046  Solved: 749[Submit][Statu ...

  8. [LeetCode] Insert Delete GetRandom O(1) 常数时间内插入删除和获得随机数

    Design a data structure that supports all following operations in average O(1) time. insert(val): In ...

  9. Python 随机数用法

    1. random.seed(int) 给随机数对象一个种子值,用于产生随机序列. 对于同一个种子值的输入,之后产生的随机数序列也一样. 通常是把时间秒数等变化值作为种子值,达到每次运行产生的随机系列 ...

随机推荐

  1. Sql视图创建语句

    create view [dbo].[AllUsers] as select u.UserId, u.Firstname, u.Lastname, u.ts, am.Email, au.UserNam ...

  2. 判断移动端js代码

    var ua=navigator.userAgent.toLowerCase(); var contains=function (a, b){ if(a.indexOf(b)!=-1){return ...

  3. 4-pwd 打印当前工作目录

    pwd print name of current/working directory 打印当前工作目录 [语法]: pwd [选项] [参数] [功能介绍] pwd命令以绝对路径的方式显示用户当前工 ...

  4. Windows下Php安装mongodb扩展失败

    查看php版本 下载对应的mongodb插件 将php_mongo.dll文件复制到php安装目录下的ext下 重启apache Apache –k restart 浏览器php.info( )测试 ...

  5. HTML5基础知识(2)--标题标签的使用

    1.HTML文档中包含各种级别的标题,各种级别的标题由<h1>到<h6>元素来定义,<h1>至<h6>标题标记中的字母h是英文headline的简称.其 ...

  6. ART、JIT、AOT、Dalvik之间的关系

    原文地址: https://github.com/ZhaoKaiQiang/AndroidDifficultAnalysis/blob/master/10.ART%E3%80%81JIT%E3%80% ...

  7. iOS开发--利用MPMoviePlayerViewController播放视频简单实现

    一.MPMoviePlayerViewController和MPMoviePlayerController区分开,前者继承自NSObject,后者继承自UIViewController 二.MPMov ...

  8. 【BZOJ 4516】【SDOI 2016】生成魔咒

    http://www.lydsy.com/JudgeOnline/problem.php?id=4516 后缀自动机直接做...省选时cena评测竟然没有卡掉map 每次加一个字符,增加的子串数目为n ...

  9. 【UOJ #147】【NOIP 2015】斗地主

    http://uoj.ac/problem/147 搜索时先枚举三顺子,双顺子和单顺子,然后贪心带牌和成三成双成单出. #include<cstdio> #include<cstri ...

  10. 【ASP.NET Identity系列教程(三)】Identity高级技术

    注:本文是[ASP.NET Identity系列教程]的第三篇.本系列教程详细.完整.深入地介绍了微软的ASP.NET Identity技术,描述了如何运用ASP.NET Identity实现应用程序 ...