題意給乙個序列(<=1e6)給乙個字符集大小為n且<=100 每次1/n的概率生成其中乙個字元 求每個字首生成的期望
公式:dp[i]=dp[next[i]]+n^i;
證明
#include
#define rep(i,x,y) for(register int i = x ;i <= y; ++ i)
#define repd(i,x,y) for(register int i = x ; i >= y; -- i)
using
namespace
std;
typedef
long
long ll;inline
char gc()
return *s++;
}template
inline
void read(t&x)
while(!isdigit(c));
do while(isdigit(c));
}const
int out_len = 1024 * 1024;
char obuf[out_len], *oh = obuf;
inline
void write_char(char c)
template
inline
void w(t x)
}inline
void flush()
const
int mod = 1e9 + 7,m = 1e6+50;
int n,m,nxt[m],a[m],f[m];
void get()
}int main()
rep(i,1,m) w(f[i]),write_char('\n');
flush();
return
0;}
如果不想背公式可以像我一樣n*m 卡卡常數即可
設dp[i]表示第i個字首的期望生成次數 那麼我該怎麼轉移來呢 首先我隨機生成乙個 那麼至少期望步數是+1 那麼我剩下部分怎麼辦我就列舉字符集 然後算一下我從上一次匹配這個到我這裡期望差是多少 即可 所以可以先kmp 但是kmp直接暴力跳躍next會出問題所以先像ac自動機一樣預處理出這個轉移然後每次可以o(1)做了
dp[i]=1+(1/n)sigma(j!=i)
#include
#include
#include
#define n 1000010
#define mod 1000000007
using
namespace
std;
inline
char gc()
return *s++;
}inline
int read()
while(isdigit(ch)) x=x*10+ch-'0',ch=gc();
return x*f;
}const
int out_len = 1024 * 1024;
char obuf[out_len], *oh = obuf;
inline
void write_char(char c)
template
inline
void w(t x)
}inline
void flush()
int dp[n],n,m,a[n],nxt[n],trans[n][101];
inline
int calc(const
int &a,const
int &b)
int main()
}for (int i=1;i<=m;++i) w(dp[i]),write_char('\n');
flush();
return
0;}
BJ 集訓測試13 平行
二維直角座標系中有n個點,它們的橫 縱座標的絕對值都不超過10。一次操作,你可以選擇某3個不共線的點a b c。然後以ab為對角線 c為另一頂點繪製平行四邊形abcd,然後用點d替換點c 即刪去點c保留點a b d 則d是確定並且唯一的。最初,n個點的座標互不相同。操作過程中這些點的座標可以重合。但...
BJ 集訓測試10 城市
圓上均勻分布n 個點 然後 在這n個點中連n 3條邊 且這些邊不相交 有q次詢問每次詢問兩點間的最短距離 因為原圖是平面圖所以可以考慮轉成對偶圖 然後點分治 不想寫對偶圖 點分治可以考慮邊分治 每次選擇一條邊 將這條邊左右的邊的數量盡量平均分布 因為這題比較特殊是在乙個圓環上 所以考慮 我給所有點標...
BJ 集訓測試12 coin
題意 有n種貨幣,每種貨幣有乙個價值vi,並且滿足任意兩種貨幣的價值成倍數關係。即對於第i種貨幣和第j種貨幣,有vi整除vj,或者vj整除vi。現在給出這n種貨幣的價值,請你計算有多少種方案能湊出價值為m的貨幣組合。假設每種貨幣的數量是無限的,貨幣的價值互不相同。為了保證有解,我們約定存在一種貨幣的...