zoukankan      html  css  js  c++  java
  • [luogu3334]抛硬币

    (数据范围的公式渲染有一些问题,大概是$ale ble 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_{iin S}pre_{i}$(本来是一个后缀除以整个串)

    然后这道题的坑点在于要用分数表示,之后就需要高精度

    通分即先将分母都改为$pre_{n}$的分母,之后分子计算需要高精乘和除单精,可以做到$o(L^{2})$

    高精度gcd通过除以2以及相减可以做到$o(L^{2})$(其中$L=2cdot 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("
    ");
     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 }
    View Code
  • 相关阅读:
    前端知识点回顾之重点篇——ES6的async函数和module
    前端知识点回顾——Javascript篇(五)
    前端知识点回顾之重点篇——ES6的Iterator和Generator
    前端知识点回顾之重点篇——ES6的Promise对象
    前端知识点回顾——Javascript篇(四)
    前端知识点回顾之重点篇——JavaScript异步机制
    前端知识点回顾之重点篇——面向对象
    JS设计模式(9)享元模式
    JS设计模式(8)模板方法模式
    JS设计模式(7)组合模式
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/14217058.html
Copyright © 2011-2022 走看看