T1 药品试验
首先不难发现的是:
{ a = ( 1 − α ) β b = ( 1 − α ) ( 1 − β ) + α β c = α ( 1 − β ) \begin{cases} a=(1-\alpha)\beta\\ b=(1-\alpha)(1-\beta)+\alpha\beta\\ c=\alpha(1-\beta) \end{cases} ⎩⎪⎨⎪⎧a=(1−α)βb=(1−α)(1−β)+αβc=α(1−β)
然后化一下递推式:
p i = a p i − 1 + b p i + c p i + 1 p i + 1 = 1 − b c p i − a c p i − 1 \begin{aligned} p_i&=ap_{i-1}+bp_i+cp_{i+1}\\ p_{i+1}&=\frac{1-b}{c}p_i-\frac{a}{c}p_{i-1} \end{aligned} pipi+1=api−1+bpi+cpi+1=c1−bpi−capi−1
但是我们还不知道 p 1 p_1 p1 的值,没办法递推。
我的处理方法是这样的,将每个 p i p_i pi 表示成 k i p 1 k_ip_1 kip1 的形式(就是用 p 1 p_1 p1 表示 p i p_i pi)。
那么令 A = 1 − b c A=\frac{1-b}{c} A=c1−b, B = − a c B=-\frac{a}{c} B=−ca,那么:
p i + 1 = A p i + B p i − 1 p i + 1 = ( A k i + B k i − 1 ) p 1 \begin{aligned} p_{i+1}&=Ap_i+Bp_{i-1}\\ p_{i+1}&=(Ak_i+Bk_{i-1})p_1 \end{aligned} pi+1pi+1=Api+Bpi−1=(Aki+Bki−1)p1
然后我们就可以用 p 1 p_1 p1 把 p 2 n p_{2n} p2n 表示出来,由于 p 2 n = 1 p_{2n}=1 p2n=1,就可以解出 p 1 p_1 p1,然后就可以推了。
时间复杂度 O ( n ) O(n) O(n)。
此外,这道题的做法还有很多,也有 O ( log n ) O(\log n) O(logn) 的做法,这里不赘述。
#include<bits/stdc++.h>
using namespace std;
const int N=1e7+5,P=1e9+7;
int n,alpha,beta,f,g,k;
inline int add(int x,int y) {return x+y>=P?x+y-P:x+y;}
inline int dec(int x,int y) {return x-y< 0?x-y+P:x-y;}
inline int mul(int x,int y) {return 1ll*x*y>=P?1ll*x*y%P:x*y;}
inline int power(int a,int b){
int ans=1;
for(;b;b>>=1,a=mul(a,a)) if(b&1) ans=mul(ans,a);
return ans;
}
int main(){
scanf("%d%d%d",&n,&alpha,&beta);
int a=mul(dec(1,alpha),beta),c=mul(alpha,dec(1,beta)),b=add(mul(dec(1,alpha),dec(1,beta)),mul(alpha,beta));
int inv=power(c,P-2),A=mul(dec(1,b),inv),B=P-mul(a,inv);
g=A,f=add(mul(A,A),B),(n==2?k=g:1),(n==3?k=f:1);
for(int i=4,up=(n<<1);i<=up;++i){
int tmp=f;
f=add(mul(A,f),mul(B,g)),(n==i?k=f:1),g=tmp;
}
printf("%d\n",mul(k,power(f,P-2)));
return 0;
}
T2 小猫钓鱼
这道题非常可惜,因为数组开小的原因从 100 100 100 掉到了 30 30 30,rank1 掉到了 rank7。
其实题目本身也没什么难度,直接按照题意模拟即可。
#include<bits/stdc++.h>
using namespace std;
const int N=105,M=1e5+5;
queue<int>Q[N];
int n,m,l,s,T,L,R,tot;
int vis[N],out[M],d[M],a[N][N],pos[M];
void Clear(){
L=1,R=0,tot=0;
memset(vis,0,sizeof(vis));
memset(pos,0,sizeof(pos));
}
void discrete(){
sort(d+1,d+tot+1);
int k=unique(d+1,d+tot+1)-d-1;
for(int i=1;i<=n;++i)
for(int j=1;j<=l;++j)
a[i][j]=lower_bound(d+1,d+k+1,a[i][j])-d;
s=lower_bound(d+1,d+k+1,s)-d;
}
int main(){
while(~scanf("%d%d%d%d%d",&n,&m,&l,&s,&T)){
if(n==-1) break;
Clear(),d[++tot]=s;
for(int i=1;i<=n;++i){
for(int j=1;j<=l;++j) scanf("%d",&a[i][j]),d[++tot]=a[i][j];
}
discrete();
for(int i=1;i<=n;++i)
for(int j=1;j<=l;++j) Q[i].push(a[i][j]);
int num=n;
for(int cas=1;cas<=T;++cas){
if(num<=1) break;
for(int i=1;i<=n;++i)if(!vis[i]){
int x=Q[i].front();Q[i].pop();
if(L<=R){
if(x==s){
for(int j=L;j<=R;++j) Q[i].push(out[j]),pos[out[j]]=0;
Q[i].push(x),L=1,R=0;
}
else{
if(pos[x]){
int now=pos[x];
for(int j=now;j<=R;++j) Q[i].push(out[j]),pos[out[j]]=0;
Q[i].push(x),R=now-1;
}
else out[++R]=x,pos[x]=R;
}
}
else out[L=R=1]=x,pos[x]=1;
if(Q[i].empty()) vis[i]=cas,num--;
}
}
for(int i=1;i<=n;++i){
if(vis[i]) printf("%d ",-vis[i]);
else printf("%d ",Q[i].size());
}
puts("");
for(int i=1;i<=n;++i){
while(!Q[i].empty()) printf("%d ",d[Q[i].front()]),Q[i].pop();
puts("");
}
}
return 0;
}
T3 迷雾华光
还没有写。