[bzoj1416]神奇的口袋

容易发现操作任意次并不会改变每一个点的概率(因为每一个点加d的概率相同,期望与原数成比例),然后直接输出即可(要用高精度)

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N 20005
 4 int n,m,k,x,s,a[N],vis[N],p[N],mi[N],sum[N];
 5 void calc(){
 6     memset(a,0,sizeof(a));
 7     a[0]=a[1]=1;
 8     for(int i=1;i<N-4;i++)
 9         for(int j=1;j<=sum[i];j++){
10             a[1]=a[1]*i;
11             for(int k=2;k<=a[0];k++){
12                 a[k]=a[k]*i+a[k-1]/10;
13                 a[k-1]%=10;
14             }
15             while(a[a[0]]>9){
16                 a[a[0]+1]=a[a[0]]/10;
17                 a[a[0]++]%=10;
18             }
19         }
20     for(int i=a[0];i;i--)printf("%d",a[i]);
21 }
22 int main(){
23     for(int i=2;i<N-4;i++){
24         if (!vis[i])p[++p[0]]=i;
25         for(int j=1;(j<=p[0])&&(i*p[j]<N-4);j++){
26             vis[i*p[j]]=1;
27             mi[i*p[j]]=p[j];
28             if (i%p[j]==0)break;
29         }
30     }
31     scanf("%d%d%d",&n,&m,&k);
32     for(int i=1;i<=n;i++){
33         scanf("%d",&a[i]);
34         s+=a[i];
35     }
36     for(int i=1;i<=m;i++){
37         scanf("%*d%d",&x);
38         sum[a[x]]++;
39         sum[s]--;
40         a[x]+=k;
41         s+=k;
42     }
43     for(int i=N-5;i;i--){
44         if (vis[i]){
45             sum[mi[i]]+=sum[i];
46             sum[i/mi[i]]+=sum[i];
47             sum[i]=0;
48         }
49     }
50     calc();
51     printf("/");
52     for(int i=N-5;i;i--)sum[i]*=-1;
53     calc();
54 }
View Code
原文地址:https://www.cnblogs.com/PYWBKTDA/p/11765882.html