• [BJOI2019]光线(DP)


    降智了……

    当你走头无路的时候就应该知道瞎搞一个DP:

    $p[i]$ 表示光射入第 $1$ 块玻璃时,从第 $i$ 块玻璃出去的光量。

    $q[i]$ 表示光射入第 $i$ 块玻璃时,从第 $i$ 块玻璃出去的光亮。

    为什么是第 $i$ 块呢?因为我们最后只关注 $p[n]$,所以我们关注的反射都是前 $i$ 块射向第 $i+1$ 块(也就是 $q[i]$)和从第 $i+1$ 块射向前 $i$ 块(也就是 $b_{i+1}$)。

    初始状态 $p[1]=a_1,q[1]=b_1$。答案为 $p[n]$。

    随便画个图得到转移:

    $$p[i]=dfrac{p[i-1]a_i}{1-q[i-1]b_i}$$

    $$q[i]=b_i+dfrac{q[i-1]a_i^2}{1-q[i-1]b_i}$$

    时间复杂度 $O(nlog)$。可以做到 $O(n)$,但是懒得写了。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=500050,mod=1000000007,inv100=570000004;
    #define FOR(i,a,b) for(int i=(a);i<=(b);i++)
    #define ROF(i,a,b) for(int i=(a);i>=(b);i--)
    #define MEM(x,v) memset(x,v,sizeof(x))
    inline int read(){
        int x=0,f=0;char ch=getchar();
        while(ch<'0' || ch>'9') f|=ch=='-',ch=getchar();
        while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
        return f?-x:x;
    }
    int n,a[maxn],b[maxn],f[maxn],g[maxn];
    inline int add(int x,int y){return x+y<mod?x+y:x+y-mod;}
    inline int sub(int x,int y){return x<y?x-y+mod:x-y;}
    inline int mul(int x,int y){return 1ll*x*y%mod;}
    inline int qpow(int a,int b){
        int ans=1;
        for(;b;b>>=1,a=mul(a,a)) if(b&1) ans=mul(ans,a);
        return ans;
    }
    int main(){
        n=read();
        FOR(i,1,n) a[i]=mul(read(),inv100),b[i]=mul(read(),inv100);
        f[1]=a[1];g[1]=b[1];
        FOR(i,2,n){
            int inv=qpow(sub(1,mul(g[i-1],b[i])),mod-2);
            f[i]=mul(mul(f[i-1],a[i]),inv);
            g[i]=add(b[i],mul(mul(mul(a[i],a[i]),g[i-1]),inv));
        }
        printf("%d
    ",f[n]);
    }
    View Code
  • 相关阅读:
    记录Log4Net的使用
    利用Ihttpmodel实现网站缓存,解决Server.Transfer 直接输出HTML源代码的问题
    ASP.NET利用byte检测上传图片安全
    通过cmd命令安装、卸载、启动和停止Windows Service(InstallUtil.exe)-大壮他哥
    winform利用代码将控件置于顶端底端
    查询
    字符数组实例化
    三维数组
    填充和批量替换
    遍历二维数组
  • 原文地址:https://www.cnblogs.com/1000Suns/p/11203818.html
Copyright © 2020-2023  润新知