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) 给随机数对象一个种子值,用于产生随机序列. 对于同一个种子值的输入,之后产生的随机数序列也一样. 通常是把时间秒数等变化值作为种子值,达到每次运行产生的随机系列 ...
随机推荐
- [HDOJ5451]Best Solver(乱搞)
题目:http://acm.hdu.edu.cn/showproblem.php?pid=5451 分析:A=5+2根号6 B=6-2根号6 n=1+2^x 那么A^n+B^n是整数 注意到0< ...
- Android之Activity启动模式
正常模式 每个应用都有一个任务栈,任务栈中保存着已创建的Activity,先创建的Activity先入栈,栈顶是当前正在显示的activity(running),这是正常模式下的Activity的管理 ...
- 二、处理MVC多级目录问题——以ABP为基础架构的一个中等规模的OA开发日志
就个人感觉而言.ASP.NET MVC是一种非常反人类的设计.(我没有接触过Java的MVC,不知道两者是否一样.如果一样,那么搞Java的同学也挺可怜.)尤其是MVC的路由机制,灰常灰常反动.路由所 ...
- HTTP 405 错误 – 方法不被允许 (Method not allowed)
HTTP 协议定义一些方法,以指明为获取客户端(如您的浏览器或我们的 CheckUpDown 机器人)所指定的具体网址资源而需要在 Web 服务器上执行的动作.则这些方法如下: 介绍 OPTIONS( ...
- 浏览器XMLHttpRequest案例
/* Cross-Browser XMLHttpRequest v1.2 ================================= Emulate Gecko 'XMLHttpRequest ...
- css-@keyframes动画
详细w3c这里 http://www.cnblogs.com/happyPawpaw/archive/2012/09/12/2681348.html Internet Explorer 10.Fire ...
- dede使用方法----如何调用最新文章,最热文章,友情链接
dede如何调用最新文章 {dede:arclist row='5' titlelen='50' orderby ='pubdate'} <li><a h ...
- windows下为mysql添加日志
mysql的配置文件 [mysqld] …… log-error="D:/phpStudy/log/mysql/mysql_log_err.txt" log="D:/ph ...
- 算法与数据结构之交换(SWAP)排序
#include<stdio.h> #include<stdlib.h> void swap(int x,int y); void swap_p(int *px,int *py ...
- bzoj4264: 小C找朋友
hash大法好 #include <iostream> #include <cstdio> #include <cstring> #include <cmat ...