题目链接

题意

给出参数\(C_1,C_2,P\)按如下方式生成一个长度为\(n \times m\)的序列\(x\):

\(x_0 = C_1,x_1=C2\)

\(x_i=(x_{i-1}+x_{i-1}) \% P \; (i > 1)\)

然后按如下方式生成一个长度为\(n \times m\)的序列\(a\)

\[a_i=\sum\limits_{j=0}^ix_j^2\%P
\]

然后现在进行\(Q\)次操作,每次操作给出两个参数\(k1,k2\)。表示交换\(k1,k2\)的值。

然后把序列\(a\)按顺序放到一个\(n \times m\)的网格中。

要求出一种方案,使得从\((1,1)\)走到\((n,m)\),所经过的数字排列起来字典序最小。

思路

容易发现,其实就是快速求出\(a_i\)。

然后就推一下式子。

\[x_i^2=x_{i-1}^2+2x_{i-1}x_{i-2}+x_{i-2}^2
\]

\[x_{i-1}^2=x_i^2-x_{i-2}^2-2x_{i-1}x_{i-2}
\]

\[x_{i-1}^2=(x_i+x_{i-2})\times(x_i-x_{i-2}) - 2x_{i-1}x_{i-2}
\]

\[x_{i-1}^2=x_{i-1}(x_i+x_{i-2}) - 2x_{i-1}x_{i-2}
\]

\[x_{i-1}^2=x_ix_{i-1}+x_{i-1}x_{i-2}-2x_{i-1}x_{i-2}
\]

\[x_{i-1}^2=x_ix_{i-1}-x_{i-1}x_{i-2}
\]

也就是说

\[x_i^2=x_{i+1}x_i-x_ix_{i-1}
\]

这样也就是容易得到

\[a_i=x_{i+1}x_i-C_1(C_2-C_1)
\]

所以只要可以快速的求出斐波那契数列第\(i\)项就可以了。

如果直接每次矩阵快速幂会\(TLE\)

所以先预处理出\(fbi_1,fbi_2,fbi_3...fbi_m\)和\(fbi_m,fbi_{2m},fbi_{3m}...fbi{nm}\)的转移矩阵。

对于第\(i\)行第\(j\)列的数,直接\(O(2^3)\)求出

代码

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<cstring>
#include<bitset>
#include<map>
using namespace std;
typedef long long ll;
const int N = 500000 + 100,INF = 1e9 + 7;
map<ll,ll>ma;
ll read() {
ll x=0,f=1;char c=getchar();
while(c<'0'||c>'9') {
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9') {
x=x*10+c-'0';
c=getchar();
}
return x*f;
}
int C1,C2,mod,n,m,Q;
namespace FBI {
struct node {
int a[3][3],n,m;
node() {
memset(a,0,sizeof(a));
}
node(int x) {
n = m = x;
memset(a,0,sizeof(a));
for(int i = 1;i <= x;++i) a[i][i] = 1;
}
node(int x,int y) {
n = x,m = y;
memset(a,0,sizeof(a));
}
};
node operator * (const node &A,const node &B) {
int n = A.n,m = B.m,K = A.m;
node ret(n,m);
for(int k = 1;k <= K;++k) {
for(int i = 1;i <= n;++i) {
for(int j = 1;j <= m;++j) {
ret.a[i][j] += 1ll * A.a[i][k] * B.a[k][j] % mod;
ret.a[i][j] %= mod;
}
}
}
return ret;
}
node fbi(1,2),tmp(2,2),lin[N],row[N];
void pre() {
fbi.a[1][1] = C2,fbi.a[1][2] = C1;
tmp.a[1][1] = tmp.a[1][2] = tmp.a[2][1] = 1; row[0].n = row[0].m = 2;row[0].a[1][1] = row[0].a[2][2] = 1;
for(int i = 1;i <= m;++i) row[i] = row[i - 1] * tmp; lin[0].n = lin[0].m = 2;
lin[0].a[1][1] = lin[0].a[2][2] = 1;
for(int i = 1;i <= n;++i) lin[i] = lin[i - 1] * row[m];
}
int solve(ll x) {
if(x == -1) return (C2 - C1 + mod) % mod;
if(x == 0) return C1;
if(x == 1) return C2;
--x;
int y = x % m;
x /= m;
return (fbi * lin[x] * row[y]).a[1][1];
}
int main(ll x) {
return (1ll * solve(x + 1) * solve(x) % mod - 1ll * C1 * (C2 - C1) % mod + mod) % mod;
}
}
ll p(ll x,ll y) {
ll z = (x - 1) * m + y;
if(ma[z]) return ma[z];
return z;
}
ll cnt = 1,ans;
void solve(int x,int y) {
++cnt;
if(x == n && y == m) return;
int down = INF,right = INF;
if(x != n) down = FBI::main(p(x + 1,y));
if(y != m) right = FBI::main(p(x,y + 1));
if(down <= right) {
ans += cnt * down % mod;
ans %= mod;
solve(x + 1,y);
}
else {
ans += cnt * right % mod;
ans %= mod;
solve(x,y + 1);
}
return;
}
int main() {
n = read(),m = read(),Q = read(),mod = read(),C1 = read(),C2 = read();
for(int i = 1;i <= Q;++i) {
ll x = read(),y = read(),tx = x,ty = y;
if(ma[x]) tx = ma[x];
if(ma[y]) ty = ma[y];
ma[x] = ty;ma[y] = tx;
}
FBI::pre();
if(ma[1]) ans += FBI::main(ma[1]),ans %= mod;
else ans += FBI::main(1),ans %= mod;
solve(1,1);
cout<<ans;
return 0;
}

bzoj4490 随机数生成器Ⅱ加强版的更多相关文章

  1. bzoj4471 bzoj4490 随机数生成器Ⅱ

    Description 继NOI2014后,小H又发现了一种新的生成随机数的方法.首先,给定三个随机种子P,C1,C2(C1≤C2)生成一个序列{xi},{xi}满足对于任意的i≥0,满足以下递推式X ...

  2. 【原创】开源Math.NET基础数学类库使用(13)C#实现其他随机数生成器

                   本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新  开源Math.NET基础数学类库使用总目录:[目录]开源Math.NET基础数学类库使用总目录 前言 ...

  3. 【BZOJ-3122】随机数生成器 BSGS

    3122: [Sdoi2013]随机数生成器 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1362  Solved: 531[Submit][Sta ...

  4. BZOJ-2875 随机数生成器 矩阵乘法快速幂+快速乘

    题目没给全,吃X了... 2875: [Noi2012]随机数生成器 Time Limit: 10 Sec Memory Limit: 512 MB Submit: 1479 Solved: 829 ...

  5. [BZOJ3671][UOJ#6][NOI2014]随机数生成器

    [BZOJ3671][UOJ#6][NOI2014]随机数生成器 试题描述 小H最近在研究随机算法.随机算法往往需要通过调用随机数生成函数(例如Pascal中的random和C/C++中的rand)来 ...

  6. NOI2014 随机数生成器

    随机数生成器 [问题描述] 小H最近在研究随机算法.随机算法往往需要通过调用随机数生成函数(例如Pascal中的random和C/C++中的rand)来获得随机性.事实上,随机数生成函数也并不是真正的 ...

  7. 【BZOJ 3122】 [Sdoi2013]随机数生成器 (BSGS)

    3122: [Sdoi2013]随机数生成器 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1442  Solved: 552 Description ...

  8. Linux下对拍脚本与随机数生成器

    对拍脚本 新建一个文档 check.sh 作为对拍脚本. #!/bin/bash while(true)do #死循环 ./data > .in #运行数据生成器,将数据输出到1.in ./st ...

  9. 矩阵(快速幂):COGS 963. [NOI2012] 随机数生成器

    963. [NOI2012] 随机数生成器 ★★   输入文件:randoma.in   输出文件:randoma.out   简单对比 时间限制:1 s   内存限制:128 MB [问题描述] 栋 ...

随机推荐

  1. python 面试题

    1.os.path与sys.path的区别是什么? os.path 主要用于系统文件路径的操作 sys.path 主要是python解释器的系统环境参数的操作 2.re模块中match和search方 ...

  2. 学习day03

    1.结构标记  *****   做布局    1.<header>元素    <header></header>    ==> <div id=&quo ...

  3. Jetty 开发指南:嵌入式开发示例

    Jetty具有嵌入各种应用程序的丰富历史. 在本节中,我们将向您介绍我们的git存储库中的embedded-jetty-examples项目下的一些简单示例. 重要:生成此文档时,将直接从我们的git ...

  4. 重建程序员能力(3)-asp.net MVC框架增加Controller

        MVC在微软中提供的框架目前只是发现是asp.net用.另 8年前,我做了个MVC的Windows APP框架如果有兴趣我日后会介绍给大家,欢迎大家关注.MVC的概念网站上有很多,大家去查阅一 ...

  5. SuperMap 9D 实时数据服务学习笔记

    SuperMap 在9月份发布了结合大数据技术的9D新产品,今天就和大家介绍下iServer9D中的实时数据服务. 1.技术框架 结合Spark的streaming流处理框架,将各种数据进行批量处理. ...

  6. 一种动态写入apk数据的方法(用于用户关系绑定、添加渠道号等)

    背景: 正在开发的APP需要记录业务员与客户的绑定关系.具体应用场景如下: 由流程图可知,并没有用户填写业务人员信息这一步,因此在用户下载的APP中就已经携带了业务人员的信息. 由于业务人员众多,不可 ...

  7. linux如何批量关闭进程

    碰到需要杀掉某一类进程的时候,如何批量杀掉这些进程,使用awk命令是很好的选择. 代码: ps -ef|grep aaa|grep -v grep|awk '{print "kill -9 ...

  8. SQL Server中将多行数据拼接为一行数据(一个字符串)

    表A中id与表B中aid为一对多的关系 例如: 表A: id name a1 tom a2 lily a3 lucy 表B: id aid value b1 a1 B1 b2 a1 B2 b3 a2 ...

  9. Ubuntu 16.04 安装系统监视器System Monitor

    安装好Ubuntu 16.04 之后,如何查看系统进程,CPU等的使用情况呢,System Monitor可以做到, 安装步骤: sudo add-apt-repository ppa:fossfre ...

  10. 如莲开发平台(MIS基础框架、Java技术、B/S结构)

    关于     「如莲」是一套MIS类系统基础框架,主要用于各类“管理信息系统”的开发,也适合做网站后台开发.可省去开发时的框架搭建.规范约定.权限管理等基础工作,直接专注于业务功能实现.     「如 ...