MZOJ #78 小象涂色
分析
一道概率题
对于每一个格子,有c种颜色可以涂,所以
初始颜色为1,所以初始化:
选定区间,对于每一个格子,有一半的概率选择涂,一半的概率不涂
如果不涂,那么就是原来的颜色,所以这一轮原来的颜色的概率就是
这种颜色原来的概率的一半
如果要涂,那么涂具体一种颜色的概率为1/c
所以,涂色核心程序:
这样做当然要超时
可以小小优化一下(虽然没太大用处):
有没有简单的方法呢,或者我们做了那些无用功?
嗯,好像每个格子都是独立的,
还有,颜色的概率只与涂色的次数有关(没发现的话可以单步调试看看)
那我们可不可以集中处理呢?
直接处理出1~k次涂色的概率,求出每个格子的涂色次数后直接套就好
好主意
每个格子的涂色次数,暴力,或者差分
处理相应次数的概率:
嗯,好了
代码
暴力:
1 /************************** 2 User:Mandy.H.Y 3 Language:c++ 4 Problem:elephant 5 Algorithm: 6 **************************/ 7 8 #include<bits/stdc++.h> 9 10 using namespace std; 11 12 const int maxn = 55; 13 14 int t,n,c,k; 15 double a[maxn][105]; 16 double b[105]; 17 18 char *TT,*mo,but[(1 << 15) + 2]; 19 #define getchar() ((TT == mo && (mo = ((TT = but) + fread(but,1,1 << 15,stdin)), TT == mo)) ? -1 : *TT++) 20 template<class T>inline void read(T &x){ 21 x = 0;bool flag = 0;char ch = getchar(); 22 while(!isdigit(ch)) flag |= ch == '-',ch = getchar(); 23 while(isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48),ch = getchar(); 24 if(flag) x = -x; 25 } 26 27 template<class T>void putch(const T x){ 28 if(x > 9) putch(x / 10); 29 putchar(x % 10 | 48); 30 } 31 32 template<class T>void put(const T x){ 33 if(x < 0) putchar('-'),putch(-x); 34 else putch(x); 35 } 36 37 void file(){ 38 freopen("elephant.in","r",stdin); 39 freopen("elephant.out","w",stdout); 40 } 41 42 void readdata(){ 43 read(n);read(c);read(k); 44 memset(a,0,sizeof(a)); 45 memset(b,0,sizeof(b)); 46 for(int i = 1;i <= n; ++ i) a[i][1] = 1; 47 } 48 49 void work(){ 50 readdata(); 51 double color = ((double)1.0 / (double)c); 52 for(int z = 1;z <= k; ++ z){ 53 int l,r; 54 read(l);read(r); 55 for(int i = l;i <= r; ++ i){ 56 for(int j = 0;j < c; ++ j){ 57 a[i][j] *= 0.5; 58 b[j] = a[i][j] * color; 59 } 60 for(int j = 0;j < c; ++ j){ 61 a[i][j * j % c] += b[j];//这里,本身就只枚举一次 62 for(int x = j + 1;x < c; ++ x){//整整少了一半的时间 63 a[i][j * x % c] += b[j] + b[x]; 64 } 65 } 66 } 67 } 68 double ans = 0; 69 for(int i = 1;i <= n; ++ i){ 70 for(int j = 0;j < c; ++ j){ 71 ans += a[i][j] * j; 72 } 73 } 74 printf("%.9lf\n",ans); 75 } 76 77 int main(){ 78 file(); 79 read(t); 80 while(t --) 81 work(); 82 return 0; 83 }
满分:
1 /************************** 2 User:Mandy.H.Y 3 Language:c++ 4 Problem:elephant 5 Algorithm: 6 **************************/ 7 8 #include<bits/stdc++.h> 9 10 using namespace std; 11 12 const int maxn = 55; 13 14 int t,n,c,k; 15 int sum[maxn]; 16 double cur[maxn][105]; 17 double b[105]; 18 19 char *TT,*mo,but[(1 << 15) + 2]; 20 #define getchar() ((TT == mo && (mo = ((TT = but) + fread(but,1,1 << 15,stdin)), TT == mo)) ? -1 : *TT++) 21 template<class T>inline void read(T &x){ 22 x = 0;bool flag = 0;char ch = getchar(); 23 while(!isdigit(ch)) flag |= ch == '-',ch = getchar(); 24 while(isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48),ch = getchar(); 25 if(flag) x = -x; 26 } 27 28 template<class T>void putch(const T x){ 29 if(x > 9) putch(x / 10); 30 putchar(x % 10 | 48); 31 } 32 33 template<class T>void put(const T x){ 34 if(x < 0) putchar('-'),putch(-x); 35 else putch(x); 36 } 37 38 void file(){ 39 freopen("elephant.in","r",stdin); 40 freopen("elephant.out","w",stdout); 41 } 42 43 void readdata(){ 44 read(n);read(c);read(k); 45 memset(sum,0,sizeof(sum)); 46 memset(cur,0,sizeof(cur)); 47 memset(b,0,sizeof(b)); 48 } 49 50 void work(){ 51 readdata(); 52 double color = ((double)1.0 / (double)c); 53 for(int z = 1;z <= k; ++ z){ 54 int l,r; 55 read(l);read(r); 56 sum[l]++; 57 sum[r+1]--; 58 } 59 60 for(int i = 1;i <= n; ++ i) sum[i] += sum[i-1]; 61 cur[0][1] = 1;//初始都是颜色1 62 for(int i = 1;i <= k; ++ i){ 63 for(int j = 0;j < c; ++ j){ 64 cur[i][j] = cur[i - 1][j] * 0.5; 65 } 66 for(int j = 0;j < c; ++ j){ 67 for(int x = 0;x < c; ++ x){ 68 cur[i][j * x % c] += cur[i-1][j] * 0.5 * color; 69 } 70 } 71 } 72 73 double ans = 0; 74 for(int i = 1;i <= n; ++ i){ 75 for(int j = 0;j < c; ++ j){ 76 ans += cur[sum[i]][j] * j; 77 } 78 } 79 printf("%.9lf\n",ans); 80 } 81 82 int main(){ 83 // file(); 84 read(t); 85 while(t --) 86 work(); 87 return 0; 88 }
非做顽石不可,哪管他敬仰暗唾