BM递推杜教版【扩展】
也就是模数不是质数的时候,
//下面的板子能求质数和非质数,只需要传不同的参数。
- #include <cstdio>
- #include <cstdlib>
- #include <cassert>
- #include <cstring>
- #include <bitset>
- #include <cmath>
- #include <cctype>
- #include <unordered_map>
- #include <iostream>
- #include <algorithm>
- #include <string>
- #include <vector>
- #include <queue>
- #include <map>
- #include <set>
- #include <sstream>
- #include <iomanip>
- using namespace std;
- typedef long long ll;
- typedef vector<long long> VI;
- typedef unsigned long long ull;
- const ll inff = 0x3f3f3f3f3f3f3f3f;
- const ll mod=1e9;
- #define FOR(i,a,b) for(int i(a);i<=(b);++i)
- #define FOL(i,a,b) for(int i(a);i>=(b);--i)
- #define SZ(x) ((long long)(x).size())
- #define REW(a,b) memset(a,b,sizeof(a))
- #define inf int(0x3f3f3f3f)
- #define si(a) scanf("%d",&a)
- #define sl(a) scanf("%I64d",&a)
- #define sd(a) scanf("%lf",&a)
- #define ss(a) scanf("%s",a)
- #define pb push_back
- #define eps 1e-6
- #define lc d<<1
- #define rc d<<1|1
- #define Pll pair<ll,ll>
- #define P pair<int,int>
- #define pi acos(-1)
- ll powmod(ll a,ll b)
- {
- ll res=1ll;
- while(b)
- {
- if(b&) res=res*a%mod;
- a=a*a%mod,b>>=;
- }
- return res;
- }
- namespace linear_seq {
- const int N=;
- using int64 = long long;
- using vec = std::vector<int64>;
- ll res[N],base[N],_c[N],_md[N];
- vector<int> Md;
- void mul(ll *a,ll *b,int k) {
- FOR(i,,k+k-) _c[i]=;
- FOR(i,,k-) if (a[i]) FOR(j,,k-) _c[i+j]=(_c[i+j]+a[i]*b[j])%mod;
- for (int i=k+k-;i>=k;i--) if (_c[i])
- FOR(j,,SZ(Md)-) _c[i-k+Md[j]]=(_c[i-k+Md[j]]-_c[i]*_md[Md[j]])%mod;
- FOR(i,,k-) a[i]=_c[i];
- }
- int solve(ll n,VI a,VI b) { // a 系数 b 初值 b[n+1]=a[0]*b[n]+...
- // printf("%d\n",SZ(b));
- ll ans=,pnt=;
- int k=SZ(a);
- assert(SZ(a)==SZ(b));
- FOR(i,,k-) _md[k--i]=-a[i];_md[k]=;
- Md.clear();
- FOR(i,,k-) if (_md[i]!=) Md.push_back(i);
- FOR(i,,k-) res[i]=base[i]=;
- res[]=;
- while ((1ll<<pnt)<=n) pnt++;
- for (int p=pnt;p>=;p--) {
- mul(res,res,k);
- if ((n>>p)&) {
- for (int i=k-;i>=;i--) res[i+]=res[i];res[]=;
- FOR(j,,SZ(Md)-) res[Md[j]]=(res[Md[j]]-res[k]*_md[Md[j]])%mod;
- }
- }
- FOR(i,,k-) ans=(ans+res[i]*b[i])%mod;
- if (ans<) ans+=mod;
- return ans;
- }
- VI BM(VI s) {
- VI C(,),B(,);
- int L=,m=,b=;
- FOR(n,,SZ(s)-) {
- ll d=;
- FOR(i,,L) d=(d+(ll)C[i]*s[n-i])%mod;
- if (d==) ++m;
- else if (*L<=n) {
- VI T=C;
- ll c=mod-d*powmod(b,mod-)%mod;
- while (SZ(C)<SZ(B)+m) C.pb();
- FOR(i,,SZ(B)-) C[i+m]=(C[i+m]+c*B[i])%mod;
- L=n+-L; B=T; b=d; m=;
- } else {
- ll c=mod-d*powmod(b,mod-)%mod;
- while (SZ(C)<SZ(B)+m) C.pb();
- FOR(i,,SZ(B)-) C[i+m]=(C[i+m]+c*B[i])%mod;
- ++m;
- }
- }
- return C;
- }
- static void extand(vec &a, size_t d, int64 value = ) {
- if (d <= a.size()) return;
- a.resize(d, value);
- }
- static void exgcd(int64 a, int64 b, int64 &g, int64 &x, int64 &y) {
- if (!b) x = , y = , g = a;
- else {
- exgcd(b, a % b, g, y, x);
- y -= x * (a / b);
- }
- }
- static int64 crt(const vec &c, const vec &m) {
- int n = c.size();
- int64 M = , ans = ;
- for (int i = ; i < n; ++i) M *= m[i];
- for (int i = ; i < n; ++i) {
- int64 x, y, g, tm = M / m[i];
- exgcd(tm, m[i], g, x, y);
- ans = (ans + tm * x * c[i] % M) % M;
- }
- return (ans + M) % M;
- }
- static vec ReedsSloane(const vec &s, int64 mod) {
- auto inverse = [](int64 a, int64 m) {
- int64 d, x, y;
- exgcd(a, m, d, x, y);
- return d == ? (x % m + m) % m : -;
- };
- auto L = [](const vec &a, const vec &b) {
- int da = (a.size() > || (a.size() == && a[])) ? a.size() - : -;
- int db = (b.size() > || (b.size() == && b[])) ? b.size() - : -;
- return std::max(da, db + );
- };
- auto prime_power = [&](const vec &s, int64 mod, int64 p, int64 e) {
- // linear feedback shift register mod p^e, p is prime
- std::vector<vec> a(e), b(e), an(e), bn(e), ao(e), bo(e);
- vec t(e), u(e), r(e), to(e, ), uo(e), pw(e + );;
- pw[] = ;
- for (int i = pw[] = ; i <= e; ++i) pw[i] = pw[i - ] * p;
- for (int64 i = ; i < e; ++i) {
- a[i] = {pw[i]}, an[i] = {pw[i]};
- b[i] = {}, bn[i] = {s[] * pw[i] % mod};
- t[i] = s[] * pw[i] % mod;
- if (t[i] == ) {
- t[i] = , u[i] = e;
- } else {
- for (u[i] = ; t[i] % p == ; t[i] /= p, ++u[i]);
- }
- }
- for (size_t k = ; k < s.size(); ++k) {
- for (int g = ; g < e; ++g) {
- if (L(an[g], bn[g]) > L(a[g], b[g])) {
- ao[g] = a[e - - u[g]];
- bo[g] = b[e - - u[g]];
- to[g] = t[e - - u[g]];
- uo[g] = u[e - - u[g]];
- r[g] = k - ;
- }
- }
- a = an, b = bn;
- for (int o = ; o < e; ++o) {
- int64 d = ;
- for (size_t i = ; i < a[o].size() && i <= k; ++i) {
- d = (d + a[o][i] * s[k - i]) % mod;
- }
- if (d == ) {
- t[o] = , u[o] = e;
- } else {
- for (u[o] = , t[o] = d; t[o] % p == ; t[o] /= p, ++u[o]);
- int g = e - - u[o];
- if (L(a[g], b[g]) == ) {
- extand(bn[o], k + );
- bn[o][k] = (bn[o][k] + d) % mod;
- } else {
- int64 coef = t[o] * inverse(to[g], mod) % mod * pw[u[o] - uo[g]] % mod;
- int m = k - r[g];
- extand(an[o], ao[g].size() + m);
- extand(bn[o], bo[g].size() + m);
- for (size_t i = ; i < ao[g].size(); ++i) {
- an[o][i + m] -= coef * ao[g][i] % mod;
- if (an[o][i + m] < ) an[o][i + m] += mod;
- }
- while (an[o].size() && an[o].back() == ) an[o].pop_back();
- for (size_t i = ; i < bo[g].size(); ++i) {
- bn[o][i + m] -= coef * bo[g][i] % mod;
- if (bn[o][i + m] < ) bn[o][i + m] -= mod;
- }
- while (bn[o].size() && bn[o].back() == ) bn[o].pop_back();
- }
- }
- }
- }
- return std::make_pair(an[], bn[]);
- };
- std::vector<std::tuple<int64, int64, int>> fac;
- for (int64 i = ; i * i <= mod; ++i)
- if (mod % i == ) {
- int64 cnt = , pw = ;
- while (mod % i == ) mod /= i, ++cnt, pw *= i;
- fac.emplace_back(pw, i, cnt);
- }
- if (mod > ) fac.emplace_back(mod, mod, );
- std::vector<vec> as;
- size_t n = ;
- for (auto &&x: fac) {
- int64 mod, p, e;
- vec a, b;
- std::tie(mod, p, e) = x;
- auto ss = s;
- for (auto &&x: ss) x %= mod;
- std::tie(a, b) = prime_power(ss, mod, p, e);
- as.emplace_back(a);
- n = std::max(n, a.size());
- }
- vec a(n), c(as.size()), m(as.size());
- for (size_t i = ; i < n; ++i) {
- for (size_t j = ; j < as.size(); ++j) {
- m[j] = std::get<>(fac[j]);
- c[j] = i < as[j].size() ? as[j][i] : ;
- }
- a[i] = crt(c, m);
- }
- return a;
- }
- ll gao(VI a,ll n,ll mod,bool prime=true) {
- VI c;
- if(prime) c=BM(a); //素数使用BM
- else c=ReedsSloane(a,mod); //合数使用ReedsSloane
- c.erase(c.begin());
- FOR(i,,SZ(c)-) c[i]=(mod-c[i])%mod;
- return solve(n,c,VI(a.begin(),a.begin()+SZ(c)));
- }
- };
- ll qpow(ll a,ll b, ll mod)
- {
- ll res=;
- while(b)
- {
- if(b&) res=res*a%mod;
- a=a*a%mod,b>>=;
- }
- return res;
- }
- vector<ll>tmp;
- int n, m;
- int main()
- {
- scanf("%d%d", &n,&m);
- ll a = , b = , c, sum = ;
- tmp.push_back();tmp.push_back();
- for(int i = ;i <= *;i++)
- {
- c = (a + b) % mod;
- a = b;
- b = c;
- sum = (sum + qpow(c, m, mod)) % mod;
- tmp.push_back(sum);
- //printf("%lld\n", c);
- }
- //for(int i = 0;i <= 2*m;i++) printf("%lld\n", tmp[i]);
- printf("%lld\n", linear_seq::gao(tmp, n, mod, false));
- }
Code From:https://www.cnblogs.com/Profish/p/9738143.html
BM递推杜教版【扩展】的更多相关文章
- BM递推杜教版
#include <bits/stdc++.h> using namespace std; #define rep(i,a,n) for (long long i=a;i<n;i++ ...
- BM求线性递推模板(杜教版)
BM求线性递推模板(杜教版) BM求线性递推是最近了解到的一个黑科技 如果一个数列.其能够通过线性递推而来 例如使用矩阵快速幂优化的 DP 大概都可以丢进去 则使用 BM 即可得到任意 N 项的数列元 ...
- 杜教BM递推板子
Berlekamp-Massey 算法用于求解常系数线性递推式 #include<bits/stdc++.h> typedef std::vector<int> VI; typ ...
- 2019牛客多校第二场BEddy Walker 2——BM递推
题意 从数字 $0$ 除法,每次向前走 $i$ 步,$i$ 是 $1 \sim K$ 中等概率随机的一个数,也就是说概率都是 $\frac{1}{K}$.求落在过数字 $N$ 额概率,$N=-1$ 表 ...
- BM递推
从别的大佬处看到的模板 #include<bits/stdc++.h> #define fi first #define se second #define INF 0x3f3f3f3f ...
- ZZNU 2182 矩阵dp (矩阵快速幂+递推式 || 杜教BM)
题目链接:http://47.93.249.116/problem.php?id=2182 题目描述 河神喜欢吃零食,有三种最喜欢的零食,鱼干,猪肉脯,巧克力.他每小时会选择一种吃一包. 不幸的是,医 ...
- 牛客多校第九场 A The power of Fibonacci 杜教bm解线性递推
题意:计算斐波那契数列前n项和的m次方模1e9 题解: $F[i] – F[i-1] – F[i-2] = 0$ $F[i]^2 – 2 F[i-1]^2 – 2 F[i-2]^2 + F[i-3] ...
- 2018 焦作网络赛 L Poor God Water ( AC自动机构造矩阵、BM求线性递推、手动构造矩阵、矩阵快速幂 )
题目链接 题意 : 实际上可以转化一下题意 要求求出用三个不同元素的字符集例如 { 'A' .'B' .'C' } 构造出长度为 n 且不包含 AAA.BBB CCC.ACB BCA.CAC CBC ...
- 【THUSC2017】【LOJ2981】如果奇迹有颜色 DP BM 打表 线性递推
题目大意 有一个 \(n\) 个点的环,你要用 \(m\) 中颜色染这 \(n\) 个点. 要求连续 \(m\) 个点的颜色不能是 $1 \sim m $ 的排列. 两种环相同当且仅当这两个环可以在旋 ...
随机推荐
- 基于DigitalOcean+LAMP+WordPress搭建个人网站
1. 注册DigitalOcean并新建主机 为了搭建个人网站首先需要一个可以在公网范围访问的主机,可以选用国内如阿里云.国外如DigitalOcean的各种云主机提供商,这里选用DigitalOce ...
- Flask源码之:配置加载
加载配置文件的思路: 1. 读取配置文件中的所有键值对,并将键值对全都放到Config对象.(Config是一个字典,因为它继承了Dict) 2. 把包含所有配置文件的Config对象,赋值给 app ...
- 开灯问题—C语言
开灯问题 有n盏灯,编号为1~n.第1个人把所有灯打开,第2个人按下所有编号为2的倍数开关(这些灯将被关掉),第3个人按下所有编号为3的倍数的开关,以此类推.一共有k个人,问最后哪些灯是开着?输入n和 ...
- centos7中mysql的rpm包安装
解决依赖 yum remove mysql-libs 执行命令:yum -y install autoconf 安装依赖 yum -y install autoconf 安装mysql rpm -iv ...
- U9单据打印模板自定义扩展字段显示名称
UBF打印模板中,单据自定义扩展字段显示均为扩展字段值集值编码,而在实际运用过程中打印时需要显示扩展字段名称,具体实现方法如下 方式一:采用SQL系统定义函数[dbo].[fn_GetSegName] ...
- ubuntu supervisor管理uwsgi+nginx
一.概述 superviosr是一个Linux/Unix系统上的进程监控工具,他/她upervisor是一个Python开发的通用的进程管理程序,可以管理和监控Linux上面的进程,能将一个普通的命令 ...
- 记一次node爬虫经历,手把手教你爬虫
今天业务突然来了个爬虫业务,爬出来的数据以Excel的形式导出,下班前一个小时开始做,加班一个小时就做好了.因为太久没做爬虫了!做这个需求都是很兴奋! 需求说明 访问网站 (循环)获取页面指定数据源 ...
- Parameter 0 of method sqlSessionTemplate in org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration required a single bean, but 2 were found:
Parameter 0 of method orderSqlSessionFactory in com.config.MultipleDBConfig required a single bean, ...
- 2019 魔域java面试笔试题 (含面试题解析)
本人5年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.魔域等公司offer,岗位是Java后端开发,因为发展原因最终选择去了魔域,入职一年时间了,也成为了面试官,之 ...
- 【MySQL】数据库中间件Atlas
1.介绍 Atlas 是由 Qihoo 360公司Web平台部基础架构团队开发维护的一个基于MySQL协议的数据中间层项目.它在MySQL官方推出的MySQL-Proxy 0.8.2版本的基础上,修改 ...