日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

P5110-块速递推【特征方程,分块】

發布時間:2023/12/3 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 P5110-块速递推【特征方程,分块】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

正題

題目鏈接:https://www.luogu.com.cn/problem/P5110


題目大意

數列aaa滿足
an=233an?1+666an?2,a0=0,a1=1a_n=233a_{n-1}+666a_{n-2},a_0=0,a_1=1an?=233an?1?+666an?2?,a0?=0,a1?=1
TTT組詢問給出nnnana_nan?

1≤T≤5×1071\leq T\leq 5\times 10^71T5×107nnnunsigned?long?long\text{unsigned long long}unsigned?long?long范圍內


解題思路

上面那個遞推式的特征方程就是x2?233x?666x^2-233x-666x2?233x?666,直接帶式子解出來x0=233+569532,x1=233?569532x_0=\frac{233+\sqrt{56953}}{2},x_1=\frac{233-\sqrt{56953}}{2}x0?=2233+56953??,x1?=2233?56953??

然后設an=c0x0n+c1x1na_n=c_0x_0^n+c_1x_1^nan?=c0?x0n?+c1?x1n?,那么帶入a0a_0a0?a1a_1a1?就有
{c0+c1=0c0233+569532+c1233?569532=1\left\{\begin{matrix}c_0+c_1=0\\c_0\frac{233+\sqrt{56953}}{2}+c_1\frac{233-\sqrt{56953}}{2}=1\end{matrix}\right.{c0?+c1?=0c0?2233+56953??+c1?2233?56953??=1?
解出來有c0=156953,c1=?156953c_0=\frac{1}{\sqrt{56953}},c_1=-\frac{1}{\sqrt{56953}}c0?=56953?1?,c1?=?56953?1?

這樣我們就可以O(Tlog?n)O(T\log n)O(Tlogn)求答案了,但是還是不夠。

先根據歐拉定理讓nnn模上φ(P)\varphi(P)φ(P)縮小范圍

然后分塊處理快速冪,處理出xix^ixixiP(i∈[0,P])x^{i\sqrt P}(i\in[0,\sqrt P])xiP?(i[0,P?]),這個是O(P)O(\sqrt P)O(P?)的,然后每次把nnn分為整塊的成上末尾的就好了。

時間復雜度O(P+T)O(\sqrt P+T)O(P?+T)


code

#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #define ll long long using namespace std; const ll P=1e9+7,Phi=P-1; const ll sq=188305837,T=32000; ll Q,n,p0[T+1],p1[T+1],P0[T+1],P1[T+1],ans; ll pw0(ll x){return P0[x/T]*p0[x%T]%P;} ll pw1(ll x){return P1[x/T]*p1[x%T]%P;} namespace Mker {unsigned long long SA,SB,SC;void init(){scanf("%llu%llu%llu",&SA,&SB,&SC);}unsigned long long rand(){SA^=SA<<32,SA^=SA>>13,SA^=SA<<1;unsigned long long t=SA;SA=SB,SB=SC,SC^=t^SA;return SC%Phi;} } signed main() {ll inv2=(P+1)/2;ll x0=(233+sq)*inv2%P,x1=(P+233-sq)*inv2%P;p0[0]=p1[0]=P0[0]=P1[0]=1;for(ll i=1;i<=T;i++)p0[i]=p0[i-1]*x0%P,p1[i]=p1[i-1]*x1%P;for(ll i=1;i<=T;i++)P0[i]=P0[i-1]*p0[T]%P,P1[i]=P1[i-1]*p1[T]%P;ll inv=233230706,c0=inv,c1=P-inv;scanf("%lld",&Q);Mker::init();while(Q--){n=Mker::rand(); // scanf("%lld",&n);ans=0;ans^=(c0*pw0(n)+c1*pw1(n))%P; // printf("%lld\n",ans);}printf("%lld\n",ans); }

總結

以上是生活随笔為你收集整理的P5110-块速递推【特征方程,分块】的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。