[luogu3334]抛硬币
(数据范围的公式渲染有一些问题,大概是$a\le b\le 100$)
同洛谷4548,推导过程省略,直接给出答案——
令$p_{H}=\frac{b}{a}$,$p_{T}=\frac{b}{b-a}$,则$pre_{i}=\prod_{j=0}^{i-1}P_{s_{j}}$($s$下标从为$[0,n)$)
令$S=\{i|s[0,i)=s[n-i,n)\}$,则答案为$\sum_{i\in S}pre_{i}$(本来是一个后缀除以整个串)
然后这道题的坑点在于要用分数表示,之后就需要高精度
通分即先将分母都改为$pre_{n}$的分母,之后分子计算需要高精乘和除单精,可以做到$o(L^{2})$
高精度gcd通过除以2以及相减可以做到$o(L^{2})$(其中$L=2\cdot 10^{3}+3$),要写成非递归形式,否则会MLE
高精度除法二分+暴力高精度乘法可以做到$o(L^{3})$(由于fft自带的常数,$o(L^{2}\log_{2}L)$甚至会TLE)
常数较大,大概可以压$10^{7}$(防止乘100后爆int)可以过
(事实上数据极水,不约分可以得到90分)
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 1005 4 #define L (N<<1) 5 #define ll long long 6 #define base 10000000 7 struct ji{ 8 int l,a[L]; 9 }zero,one,ans_zi,ans_mu,pre[N]; 10 int n,pa,pb,nex[N],rev[L<<1]; 11 char s[N]; 12 int cmp(ji x,ji y){//x<y则返回-1,x=y返回0,x>y返回1 13 if (x.l!=y.l)return 1-(x.l<y.l)*2; 14 for(int i=x.l;i;i--) 15 if (x.a[i]!=y.a[i])return 1-(x.a[i]<y.a[i])*2; 16 return 0; 17 } 18 ji add(ji x,ji y){ 19 x.l=max(x.l,y.l); 20 for(int i=1;i<=x.l;i++){ 21 x.a[i]+=y.a[i]; 22 if (x.a[i]>=base){ 23 x.a[i]-=base; 24 x.a[i+1]++; 25 } 26 } 27 if (x.a[x.l+1])x.l++; 28 return x; 29 } 30 ji dec(ji x,ji y){ 31 for(int i=1;i<=y.l;i++){ 32 if (x.a[i]<y.a[i]){ 33 x.a[i]+=base; 34 x.a[i+1]--; 35 } 36 x.a[i]-=y.a[i]; 37 } 38 while ((x.l>1)&&(!x.a[x.l]))x.l--; 39 return x; 40 } 41 ji mul(ji x,int y){ 42 x.a[1]=x.a[1]*y; 43 for(int i=2;i<=x.l;i++){ 44 x.a[i]=x.a[i]*y+x.a[i-1]/base; 45 x.a[i-1]%=base; 46 } 47 if (x.a[x.l]>=base){ 48 x.a[x.l+1]=x.a[x.l]/base; 49 x.a[x.l]%=base; 50 x.l++; 51 } 52 return x; 53 } 54 ji mul(ji x,ji y){ 55 ji ans; 56 ans.l=x.l+y.l-1; 57 memset(ans.a,0,sizeof(ans.a)); 58 for(int i=1;i<=x.l;i++) 59 for(int j=1;j<=y.l;j++){ 60 ll s=1LL*x.a[i]*y.a[j]; 61 ans.a[i+j]+=(ans.a[i+j-1]+s)/base; 62 ans.a[i+j-1]=(ans.a[i+j-1]+s)%base; 63 } 64 if (ans.a[ans.l+1])ans.l++; 65 return ans; 66 } 67 ji div(ji x,int y){ 68 int r=0; 69 for(int i=x.l;i;i--){ 70 r+=x.a[i]; 71 x.a[i]=r/y; 72 r=(r%y)*base; 73 } 74 if ((x.l>1)&&(!x.a[x.l]))x.l--; 75 return x; 76 } 77 void write(ji x){ 78 printf("%d",x.a[x.l]); 79 for(int i=x.l-1;i;i--){ 80 if (x.a[i]<1000000)printf("0"); 81 if (x.a[i]<100000)printf("0"); 82 if (x.a[i]<10000)printf("0"); 83 if (x.a[i]<1000)printf("0"); 84 if (x.a[i]<100)printf("0"); 85 if (x.a[i]<10)printf("0"); 86 printf("%d",x.a[i]); 87 } 88 } 89 ji div(ji x,ji y){ 90 ji l=zero,r=x,mid; 91 while (cmp(l,r)<0){ 92 mid=div(add(l,r),2); 93 //write(l),printf(" "),write(r),printf(" "),write(mul(mid,y)),printf("\n"); 94 if (cmp(mul(mid,y),x)<0)l=add(mid,one); 95 else r=mid; 96 } 97 return l; 98 } 99 ji gcd(ji x,ji y){ 100 int cnt=0,deep=0; 101 while (cmp(x,y)){ 102 int p1=(x.a[1]&1),p2=(y.a[1]&1); 103 if ((p1)&&(p2)){ 104 if (cmp(x,y)<0)y=dec(y,x); 105 else x=dec(x,y); 106 continue; 107 } 108 if (!p1)x=div(x,2); 109 if (!p2)y=div(y,2); 110 if ((!p1)&&(!p2))cnt++; 111 } 112 ji ans=x; 113 while (cnt--)ans=mul(ans,2); 114 return ans; 115 } 116 int main(){ 117 scanf("%d%d%s",&pa,&pb,s); 118 n=strlen(s); 119 zero.l=one.l=one.a[1]=1; 120 ans_mu=one; 121 for(int i=0;i<n;i++) 122 if (s[i]=='H')ans_mu=mul(ans_mu,pa); 123 else ans_mu=mul(ans_mu,pb-pa); 124 pre[0]=ans_mu; 125 for(int i=0;i<n;i++){ 126 pre[i+1]=mul(pre[i],pb); 127 if (s[i]=='H')pre[i+1]=div(pre[i+1],pa); 128 else pre[i+1]=div(pre[i+1],pb-pa); 129 } 130 nex[0]=nex[1]=0; 131 for(int i=1,j=0;i<n;i++){ 132 while ((j)&&(s[i]!=s[j]))j=nex[j]; 133 if (s[i]==s[j])j++; 134 nex[i+1]=j; 135 } 136 for(int i=n;i;i=nex[i])ans_zi=add(ans_zi,pre[i]); 137 ji d=gcd(ans_zi,ans_mu); 138 write(div(ans_zi,d)); 139 printf("/"); 140 write(div(ans_mu,d)); 141 }