| 小象涂色 |
| 难度级别:C; 运行时间限制:1000ms; 运行空间限制:262144KB; 代码长度限制:2000000B |
|
试题描述
|
|
小象喜欢为箱子涂色。小象现在有c种颜色,编号为0~c-1;还有n个箱子,编号为1~n,最开始每个箱子的颜色为1。小象涂色时喜欢遵循灵感:它将箱子按编号排成一排,每次涂色时,它随机选择[L,R]这个区间里的一些箱子(不选看做选0个),为之涂上随机一种颜色。若一个颜色为a的箱子被涂上b色,那么这个箱子的颜色会变成(a*b)modc。请问在k次涂色后,所有箱子颜色的编号和期望为多少? |
|
输入
|
|
第一行为T,表示有T组测试数据。
对于每组数据,第一行为三个整数n,c,k。 接下来k行,每行两个整数Li,Ri,表示第i个操作的L和R。 |
|
输出
|
|
对于每组测试数据,输出所有箱子颜色编号和的期望值,结果保留9位小数。
|
|
输入示例
|
|
3
3 2 2 2 2 1 3 1 3 1 1 1 5 2 2 3 4 2 4 |
|
输出示例
|
|
2.062500000
1.000000000 3.875000000 |
|
其他说明
|
|
数据范围:
40%的数据1 <= T <= 5,1 <= n, k <= 15,2 <= c <= 20 100%的数据满足1 <= T <= 10,1 <= n, k <= 50,2 <= c <= 100,1 <= Li <= Ri <= n |
首先,操作顺序是没有影响的,那么我们可以记录每个位置进行了多少次操作。
就可以写个DP,得出每个位置进行若干次操作后的期望颜色。
#include<cstdio> #include<cctype> #include<queue> #include<cmath> #include<cstring> #include<algorithm> #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define ren for(int i=first[x];i;i=next[i]) using namespace std; inline int read() { int x=0,f=1;char c=getchar(); for(;!isdigit(c);c=getchar()) if(c=='-') f=-1; for(;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f; } double f[55][105]; int n,c,k,cnt[55]; int main() { dwn(T,read(),1) { n=read();c=read();k=read(); memset(f,0,sizeof(f)); memset(cnt,0,sizeof(cnt)); f[0][1]=1; rep(t,0,k-1) rep(j,0,c-1) { f[t+1][j]+=f[t][j]*0.5; rep(k,0,c-1) f[t+1][(j*k)%c]+=f[t][j]*(0.5/c); } double ans=0; rep(i,1,k) { int l=read(),r=read(); rep(j,l,r) cnt[j]++; } rep(i,1,n) rep(j,0,c-1) ans+=f[cnt[i]][j]*j; printf("%.9lf\n",ans); } return 0; }