BZOJ3557: [Ctsc2014]随机数
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]随机数的更多相关文章
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- .Net使用system.Security.Cryptography.RNGCryptoServiceProvider类与System.Random类生成随机数
.Net中我们通常使用Random类生成随机数,在一些场景下,我却发现Random生成的随机数并不可靠,在下面的例子中我们通过循环随机生成10个随机数: ; i < ; i++) { Rando ...
- DotNet生成随机数的一些方法
在项目开发中,一般都会使用到“随机数”,但是在DotNet中的随机数并非真正的随机数,可在一些情况下生成重复的数字,现在总结一下在项目中生成随机数的方法. 1.随机布尔值: /// <summa ...
- JavaScript 随机数
JavaScript内置函数random(seed)可以产生[0,1)之间的随机数,若想要生成其它范围的随机数该如何做呢? 生成任意范围的随机数 //生成[100,120)之间的随机数 Math.fl ...
- SQL Server 随机数,随机区间,随机抽取数据rand(),floor(),ceiling(),round(),newid()函数等
在查询分析器中执行:select rand(),可以看到结果会是类似于这样的随机小数:0.36361513486289558,像这样的小数在实际应用中用得不多,一般要取随机数都会取随机整数.那就看下面 ...
- 随机数(random)
需求 Random rd=new Random(); 需要十以内的随机数 (0---10) System.out.println((int)((rd.nextDouble()*100)/10)); ...
- BZOJ 3555: [Ctsc2014]企鹅QQ [字符串哈希]【学习笔记】
3555: [Ctsc2014]企鹅QQ Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 2046 Solved: 749[Submit][Statu ...
- [LeetCode] Insert Delete GetRandom O(1) 常数时间内插入删除和获得随机数
Design a data structure that supports all following operations in average O(1) time. insert(val): In ...
- Python 随机数用法
1. random.seed(int) 给随机数对象一个种子值,用于产生随机序列. 对于同一个种子值的输入,之后产生的随机数序列也一样. 通常是把时间秒数等变化值作为种子值,达到每次运行产生的随机系列 ...
随机推荐
- js单选和复选框
http://blog.csdn.net/chelen_jak/article/details/44827393 http://www.gbtags.com/technology/jquerynews ...
- 面向OPENCL的ALTERA SDK
面向OPENCL的ALTERA SDK 使用面向开放计算语言 (OpenCL™) 的 Altera® SDK,用户可以抽象出传统的硬件 FPGA 开发流程,采用更快.更高层面的软件开发流程.在基于 x ...
- Swift&NodeJS 使用Alamofire进行Post(zhuan)
这篇博客主要实现Swift客户端和NodeJS后台的Post.Get请求实现. 我是一个略有点讨厌重复使用工具的人,比如这些基本功能完全可以用OC和PHP等替代,但是没办法,现在知识更新的太快啦,Sw ...
- Sharepoint 杂记
在Sharepoint中复制Settle.html,粘贴后改名为km.html,修改km.html会自动更新km.master,修改好模板后需要在站点发布. 添加List添加WebPart,继承KmW ...
- JVM执行Java程序时内存的划分
Java虚拟机在执行Java程序过程中会把它所管理的内存区域划分为若干个不同的数据区域. Java虚拟机所管理的内存包括以下几个运行时区域: 1.程序计数器(Program Couter Regist ...
- 我的第一个jsp程序-实现注册登录留言功能
1,注册功能,包括两个页面 zhuce.jsp注册页面 <%@ page language="java" contentType="text/html; chars ...
- E(X+Y), E(XY), D(X + Y)
\(X, Y\)为两个随机变量, \(p_X(x), p_Y(y)\)分别为\(X, Y\)的概率密度/质量函数, \(p(x, y)\)为它们的联合概率密度. \(E(X + Y) = E(X) + ...
- lightoj 1074 spfa判断负环
Extended Traffic Time Limit:2000MS Memory Limit:32768KB 64bit IO Format:%lld & %llu Sub ...
- 系统间通信(5)——IO通信模型和JAVA实践 下篇
7.异步IO 上面两篇文章中,我们分别讲解了阻塞式同步IO.非阻塞式同步IO.多路复用IO 这三种IO模型,以及JAVA对于这三种IO模型的支持.重点说明了IO模型是由操作系统提供支持,且这三种IO模 ...
- plsql dev引起的数据库被黑勒索比特币实现原理分析和解决方案
转自http://www.xifenfei.com/2016/11/plsql-dev-hacker-bitcoin.html afterconnect.sql是plsql dev登录后自动执行脚本, ...