BSGS
1
题意:给定 a,b,pa,b,p 求 ax=b (mod p)ax=b (mod p) 的最小正整数解,pp 为质数,保证有解。
显然 。令 t=p–√t=p, 如果我们能找到一组 (c,d) ,0<=d<t(c,d) ,0<=d<t ,使得:
那么 xx 就等于 。
我们把 b⋅ai(0<=i<t)b·ai(0<=i<t) 放在一个哈希表里,然后枚举 cc,在表里找。
复杂度
原根
设 (a,m)=1(a,m)=1 满足 ar=1 (mod m)ar=1 (mod m) 的最小正整数解称作 aa 模 的阶。
如果整数 aa 模 的阶为 ϕ(m)ϕ(m) 那么称 aa 是模 的原根。
计算原根:由于原根一般不会很大,我们可以枚举原根 aa,判断 的阶是不是 ϕ(n)ϕ(n) 。
推论:原根 gg 的 次方构成模 pp 的一个缩系。
2
题意:给定 (pp 是质数),求所有满足 的 xx。
令 为 pp 的原根,则 可以表示为: gzgz,aa 可以表示为 :
两边同取离散对数:
解线性同余方程。
概率与期望
条件概率:P(B|A)=P(A⋂B)P(B)P(B|A)=P(A⋂B)P(B)
无论两随机变量是否独立,期望的线性性始终成立。
3
题意:nn 个点的有根树,每个点是白色的,每次等概率选择一个点染黑,并且把它子树里的点都染黑。求把整颗树染黑的期望次数。
貌似不是很好做…
换个角度,整颗树染黑以后,每个点被选中的概率。
一个点被染黑,当且仅当它的一个祖先或他自己被染黑。并且他们是等概率的。
由于选中代价是1,所以期望就是概率。
因此答案为:
4
题意:给定 nn 种物品,每次购买会随机买到一种,询问买到 种物品的期望次数。
考虑我们已经买到了 kk 种物品,再继续买多少次能得到第 种物品。
设它为 xx,则:
整理得:
那么答案就是 n∑ni=11nn∑i=1n1n
如果某件事发生的概率为 pp,那么发生这件事的期望次数是
5
POJ[2069]
题意:一个软件有 ss 个子系统,会产生 种bug。某人每天发现一个bug,每个bug属于某个子系统的概率是 1/s1/s ,属于某种分类的概率是 1/n1/n 。问发现 nn 种bug,且每个子系统都发现bug的天数的期望。
设 表示已经找到了 ii 种分类, 种bug,还需要的期望天数。
6
题意:初始有 kk 只生物,这种生物只能活一天,死的时候有 的概率产生 ii 只新生物(也只能活一天),询问 天后所有生物都死的概率(包括 mm 天前死的情况)。
首先观察到每只生物是独立的,所以我们可以分开计算,最后 次方。
设 f[i]f[i] 表示 ii 天后所有生物都死的概率。转移的时候枚举第一天它产了几个子:
答案是 f[m]kf[m]k
7
BZOJ[1419]
题意:有 nn 张和 mm 张,可以中途停止拿牌,询问按照最优策略拿牌,最后的得分期望。
设 f[i][j]f[i][j] 表示还有 ii 张和 jj 张的得分期望。显然满足最优子结构性质。转移的时候如果期望小于 00 就不拿了。
8
题意:要求摆放 nn 块骨牌,但排放时会有 的概率使它左边所有挨着它的骨牌倒下,同理,右边的概率为 prpr,询问摆完 nn 块的期望次数。
设 表示摆放连续 ii 个骨牌的期望次数。
转移的时候枚举 这个骨牌放在哪里。如果设摆好左边的期望次数为 E1E1 ,右边为 E2E2。
f[i]f[i] 就等于期望往左边倒的次数×E1+×E1+期望往右边倒的次数×E2+×E2+不倒的期望次数+E1+E2+E1+E2
根据前面讲的,不倒的期望次数就是不倒的概率的倒数 11−pl−pr11−pl−pr。也就是说,前面的 11−pl−pr−1=pl+pr1−pl−pr11−pl−pr−1=pl+pr1−pl−pr 次都是往左或者往右倒的(很玄妙)。
那么,往左倒的期望次数就是 pl+pr1−pl−pr∗plpl+pr=pl1−pl−prpl+pr1−pl−pr∗plpl+pr=pl1−pl−pr,右边同理。
因此,我们可以得到:
9
[NOI2015]聪聪和可可
题意:给定无向图,两个点A,B,每次A都向着离B最近的方向走,如果两个点都可以,走编号小的那个。A如果走一次没有遇到,可以接着再走一次。B每次等概率地走到相邻的点或待在原地,求A遇上B的期望时间。
设 f[i][j]f[i][j] 表示A在 ii,B在 的答案。
pos(i,j)pos(i,j) 表示A在 ii,B在 ,下一步A的位置。因此我们需要预处理最短路,预处理 pospos,然后一波记忆化搜索。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<queue>
#define ll long long
using namespace std;
struct edge{
int to,next;
}ed[1000010];
double f[1100][1100];
int du[1100],dis[1100][1100],path[1100][1100],head[1100],sz,vis[1100][1100];
inline void add(int from,int to)
{
ed[++sz].to=to;
ed[sz].next=head[from];
head[from]=sz;
}
inline void read(int &x)
{
char c=getchar();x=0;int flag=1;
while(!isdigit(c))
{
if(c=='-') flag=-1;
c=getchar();
}
while(isdigit(c)) x=x*10+c-'0',c=getchar();
x*=flag;
}
double dfs(int A,int B)
{
if(f[A][B]!=-1) return f[A][B];
if(A==B) return f[A][B]=0;
if(path[A][B]==B||path[path[A][B]][B]==B) return f[A][B]=1;
f[A][B]=0;
int pos=path[path[A][B]][B];
for(int i=head[B];i;i=ed[i].next)
{
int v=ed[i].to;
f[A][B]+=dfs(pos,v);
}
f[A][B]+=dfs(pos,B);
f[A][B]/=(1.0*(du[B]+1));
f[A][B]+=1;
return f[A][B];
}
inline void dij(int s)
{
queue <int> q;
q.push(s);
vis[s][s]=1;
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=head[u];i;i=ed[i].next)
{
int v=ed[i].to;
if(!vis[s][v])
{
dis[s][v]=dis[s][u]+1;
vis[s][v]=1;
q.push(v);
}
}
}
}
int main()
{
int n,m,A,B;
read(n),read(m),read(A),read(B);
for(int i=1;i<=m;i++)
{
int u,v;
read(u),read(v);
add(u,v),add(v,u);
du[u]++,du[v]++;
}
for(int i=1;i<=n;i++) dij(i);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(i==j) continue;
int ind=0,Min=1e9;
for(int k=head[i];k;k=ed[k].next)
{
int v=ed[k].to;
if(dis[v][j]<Min||(dis[v][j]==Min&&v<ind))
{
Min=dis[v][j];
ind=v;
}
}
path[i][j]=ind;
}
}
for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) f[i][j]=-1;
printf("%.3lf",dfs(A,B));
return 0;
}
本文探讨了离散对数问题的解决方法,如BSGS算法及其应用,并讲解了原根的概念。此外,还讨论了几道涉及概率、期望及图论的题目,包括染色期望、生物繁殖概率等问题。

2645

被折叠的 条评论
为什么被折叠?



