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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

P4548 [CTSC2006]歌唱王国

發布時間:2023/12/3 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 P4548 [CTSC2006]歌唱王国 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

P4548 [CTSC2006]歌唱王國

題目描述

Solution

這一題在《具體數學(混泥土數學)》里講得很詳細了啊,這里相當于總結一下,想具體了解的直接看書吧。

我們先考慮字符集為222的情況,設硬幣正面朝上(H)(H)(H)的概率為ppp,反面朝上(T)(T)(T)的概率為qqq

這道題顯然需要建立一個類似KMPKMPKMP的自動機,令SiS_iSi?表示已經到達目標串的第iii個位置的狀態集合。

例如目標串為THTTHTHTTHTHTTH(以下都以這個串為例介紹這種做法),則
S2={TH,TTH,HTH,TTTH......}S5={THTTH,TTHTTH,HTHTTH......}S_2=\{TH,TTH,HTH,TTTH......\}\\ S_5=\{THTTH,TTHTTH,HTHTTH......\} S2?={TH,TTH,HTH,TTTH......}S5?={THTTH,TTHTTH,HTHTTH......}

顯然有:
S0=1+S0H+S1T+S2HS1=S0T+S4TS2=S1H+S3HS3=S2TS4=S3TS5=S4HS_0=1+S_0H+S_1T+S_2H\\ S_1=S_0T+S_4T\\ S_2=S_1H+S_3H\\ S_3=S_2T\\ S_4=S_3T\\ S_5=S_4H\\ S0?=1+S0?H+S1?T+S2?HS1?=S0?T+S4?TS2?=S1?H+S3?HS3?=S2?TS4?=S3?TS5?=S4?H
其中111表示空狀態,像S1HS_1\;HS1?H這種形式表示在S1S_1S1?狀態集合每一個元素后面加一個HHH字符之后的狀態。

這樣的話,我們就能有一個O(n3)O(n^3)O(n3)的算法。
E[x]E[x]E[x]表示達到目標串的第xxx個位置所需要的字符個數的期望,直接按照上面的狀態轉移高斯消元計算即可。

但這顯然是不夠的。

我們設N=∑i<nSi,S=SnN=\sum_{i<n} S_i,S=S_nN=i<n?Si?,S=Sn?,表示還沒有目標串的所有狀態集合,考慮用只用SSSNNN,表示出上面的式子。

于是我們可以推出:
1+N(H+T)=S+N1+N(H+T)=S+N 1+N(H+T)=S+N
因為1+N1+N1+N加上一個字符之后的狀態要么沒達到目標,要么達到目標,根據定義顯然SSSNNN不相交。

并且有:
NTHTTH=S+STTHN\;\;THTTH=S+S\;\;TTH NTHTTH=S+STTH
這一個式子我理解了很久(QAQQAQQAQ)。。
因為NNN中的元素加了THTTHTHTTHTHTTH之后一定能達到目標狀態,然而可能NNN中的元素加了THTHTH之后就已經達到目標,這樣就會在末尾多一個TTHTTHTTH,且容易發現SSSSTTHS\;\;TTHSTTH仍是不相交的。

我們考慮這種加了長度為kkk的目標串,就包含目標串的條件,顯然是ST[1..k]=ST[n?k+1,k]ST[1..k]=ST[n-k+1,k]ST[1..k]=ST[n?k+1,k],就是說STSTST有一段長度為kkkBorderBorderBorder

有了這兩個式子之后,我們就可以推出:
(1?S)(1?H?T)THTTH=S(1+TTH)(1-S)(1-H-T)\;\;THTTH=S(1+TTH) (1?S)(1?H?T)THTTH=S(1+TTH)

事實上,這里的SSS,TTTHHH,就不是單純的狀態了,這里的SSS已經是一個概率生成函數,而TTTHHH能夠表示一個概率生成函數的轉移:

G(z)G(z)G(z)為一個表示拋擲次數的概率生成函數。
G(z)=∑iPr(z=i)ziG(z)=\sum_i Pr(z=i)z^i G(z)=i?Pr(z=i)zi
其中的zzz就是表示拋擲次數的形式變元,因為下一個字符為TTT的概率為qqq,為HHH的概率為ppp,所以加一個TTT相當于G(z)?pzG(z)*pzG(z)?pz,加一個HHH相當于G(z)?qzG(z)*qzG(z)?qz

于是上式變成了
(1?G(z))(q?pz?qz)?1p3q2z5=G(z)(1+p2qz)(1-G(z))(q-pz-qz)^{-1}p^3q^2z^5=G(z)(1+p^2qz) (1?G(z))(q?pz?qz)?1p3q2z5=G(z)(1+p2qz)
解得:
G(z)=p3q2z5(1+p2qz3)(1?z)+p3q2z5G(z)=\frac{p^3q^2z^5}{(1+p^2qz^3)(1-z)+p^3q^2z^5} G(z)=(1+p2qz3)(1?z)+p3q2z5p3q2z5?
而我們要求的期望為E(x)=G′(1)E(x)=G'(1)E(x)=G(1),因此我們需要想方法求出G′(1)G'(1)G(1)

有一個特殊的方法是:

F(z)=z5/G(z)F(z)=z^5/G(z) F(z)=z5/G(z)
可以證明F(z)F(z)F(z)的均值(MeanMeanMean)和G(z)G(z)G(z)的均值相同。
因此Mean(G)=Mean(z5)?Mean(F)=p?1q?1+p?3q?2Mean(G)=Mean(z^5)-Mean(F)=p^{-1}q^{-1}+p^{-3}q^{-2}Mean(G)=Mean(z5)?Mean(F)=p?1q?1+p?3q?2

p=q=1/2p=q=1/2p=q=1/2,則有期望666次到達目標串。

而根據上面的式子,容易知道,若存在一個BorderBorderBorderxxxHHH,yyyTTT則答案Ans+=p?yq?xAns+=p^{-y}q^{-x}Ans+=p?yq?x所以只要知道有哪些長度的Border,Border,Border就能算出答案。

我們已經解決了字符集大小為222的問題,現在字符集大小為nnn的做法也是一樣的,因為這里的所有字符等概率出現,所以就不需要繼續推到,相當于每出現一個BorderBorderBorder的貢獻為nkn^knk,直接統計BorderBorderBorder長度,計算貢獻和即可。

時間復雜度O(n)O(n)O(n),有點小精度問題,我開longdouble,WAlong\;\;double,WAlongdouble,WAdouble,ACdouble,ACdouble,AC,表示一臉懵逼。

#include <vector> #include <list> #include <map> #include <set> #include <deque> #include <queue> #include <stack> #include <bitset> #include <algorithm> #include <functional> #include <numeric> #include <utility> #include <sstream> #include <iostream> #include <iomanip> #include <cstdio> #include <cmath> #include <cstdlib> #include <cctype> #include <string> #include <cstring> #include <ctime> #include <cassert> #include <string.h> //#include <unordered_set> //#include <unordered_map> //#include <bits/stdc++.h>#define MP(A,B) make_pair(A,B) #define PB(A) push_back(A) #define SIZE(A) ((int)A.size()) #define LEN(A) ((int)A.length()) #define FOR(i,a,b) for(int i=(a);i<(b);++i) #define fi first #define se secondusing namespace std;template<typename T>inline bool upmin(T &x,T y) { return y<x?x=y,1:0; } template<typename T>inline bool upmax(T &x,T y) { return x<y?x=y,1:0; }typedef long long ll; typedef unsigned long long ull; typedef long double lod; typedef pair<int,int> PR; typedef vector<int> VI;const lod eps=1e-11; const lod pi=acos(-1); const int oo=1<<30; const ll loo=1ll<<62; const int Mod=10000; const int mods=1e9+7; const int MAXN=600005; const int INF=0x3f3f3f3f;//1061109567 /*--------------------------------------------------------------------*/ inline int read() {int f=1,x=0; char c=getchar();while (c<'0'||c>'9') { if (c=='-') f=-1; c=getchar(); }while (c>='0'&&c<='9') { x=(x<<3)+(x<<1)+(c^48); c=getchar(); }return x*f; } int Pow[MAXN],hsh[MAXN],a[MAXN]; inline int upd(int x,int y,int mods){ return x+y>=mods?x+y-mods:x+y; } inline int gethash(int l,int r) { return upd(hsh[r],mods-1ll*Pow[r-l+1]*hsh[l-1]%mods,mods); } int main() {int C=read(),Case=read();while (Case--){int n=read();for (int i=1;i<=n;i++) a[i]=read();Pow[0]=1;for (int i=1;i<=n;i++) Pow[i]=1ll*Pow[i-1]*(C+1)%mods;for (int i=1;i<=n;i++) hsh[i]=(1ll*hsh[i-1]*(C+1)+a[i])%mods;int ans=0;for (int i=1,p=C%Mod;i<=n;i++,p=p*C%Mod)if (gethash(1,i)==gethash(n-i+1,n)) ans=upd(ans,p,Mod);printf("%04d\n",ans);}return 0; }

總結

以上是生活随笔為你收集整理的P4548 [CTSC2006]歌唱王国的全部內容,希望文章能夠幫你解決所遇到的問題。

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