• LOJ 3093 「BJOI2019」光线——数学+思路


    题目:https://loj.ac/problem/3093

    考虑经过种种反射,最终射下去的光线总和。往下的光线就是这个总和 * a[ i ] 。

    比如只有两层的话,设射到第二层的光线是 lst ,那么 ( lst' = ( lst + lst*b[2]*b[1] + lst*(b[2]*b[1])^2 + ... )*a[2] )

    考虑令 f[ i ] 表示 “从第 i 层下面射上来的单位光线在考虑第 i+1 层反射的情况下射下去的值” 。

    ( f[i] = b[i]+a[i]*f[i-1]*a[i] + ( b[i]+a[i]*f[i-1]*a[i] ) * b[i+1] * ( b[i]+a[i]*f[i-1]*a[i]) + ... ) 

    其中 ( b[i]+a[i]*f[i-1]*a[i] ) 就是一次反射下去的光线和。设 ( x = b[i]+a[i]*f[i-1]*a[i] ) 

    式子也就是 ( f[i]=x+x*b[i+1]*x + ... = x sumlimits_{k=0}^{infty}(b[i+1]*x)^k ) 

    然后令 lst 表示透过第 i-1 层的光线,lst' 表示透过第 i 层的光线,就有 ( lst' = (lst + lst*b[i]*f[i-1])*a[i] )

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define ll long long
    using namespace std;
    int rdn()
    {
      int ret=0;bool fx=1;char ch=getchar();
      while(ch>'9'||ch<'0'){if(ch=='-')fx=0;ch=getchar();}
      while(ch>='0'&&ch<='9')ret=ret*10+ch-'0',ch=getchar();
      return fx?ret:-ret;
    }
    const int N=5e5+5,mod=1e9+7;
    int upt(int x){while(x>=mod)x-=mod;while(x<0)x+=mod;return x;}
    int pw(int x,int k)
    {int ret=1;while(k){if(k&1)ret=(ll)ret*x%mod;x=(ll)x*x%mod;k>>=1;}return ret;}
    
    int n,a[N],b[N],f[N],ans;
    int main()
    {
      n=rdn(); int iv=pw(100,mod-2);
      for(int i=1;i<=n;i++)
        {
          a[i]=(ll)rdn()*iv%mod;
          b[i]=(ll)rdn()*iv%mod;
        }
      for(int i=1;i<=n;i++)
        {
          int x=(b[i]+(ll)a[i]*f[i-1]%mod*a[i])%mod;
          f[i]=(ll)x*pw(upt(1-(ll)x*b[i+1]%mod),mod-2)%mod;
        }
      ans=a[1];
      for(int i=2;i<=n;i++)
        ans=(1+(ll)b[i]*f[i-1])%mod*ans%mod*a[i]%mod;
      printf("%d
    ",ans);
      return 0;
    }
  • 相关阅读:
    使用正则匹配数字
    钻石和玻璃球游戏(钻石位置不固定)
    简单绘图
    未解决问题02
    Sqlite3 实现学生信息增删改查
    【Python】科赫雪花绘制
    【Python爬虫】抖音去水印
    【MATLAB】数学计算软件 MathWorks MATLAB R2020a 中文破解版
    【C语言】用指针作为形参完成数据的升序排列
    【C语言】数组名作函数参数完成数据的升序排列
  • 原文地址:https://www.cnblogs.com/Narh/p/10941818.html
Copyright © 2020-2023  润新知