題解-BJOI2019 光線

Problem

loj3093 & x谷c++

題意概要:給定 \(n\) 塊玻璃,每塊玻璃有其折射比例與反射比例(折射比例+反射比例 不必定爲 \(100\%\)),求從最上頭打下一束光,有多少比例的光能夠徹底穿越 \(n\) 塊玻璃git

\(n\leq 5\times 10^5\)spa

Solution

一眼線性高斯消元,可是我懶……物理題固然不要那麼麻煩啦code

因爲考慮到這是物理模型,用物理思想考慮——合併玻璃get

僅考慮合併兩塊玻璃,對於合併後的等價玻璃,須要算出其 從上往下與從下往上的反射透射率 共四個參數。可是我懶……因爲不須要知道最上層玻璃 從上往下的反射率 與 從下往上的透射率,因此能夠考慮每次合併最頂上的兩塊玻璃,只須要計算兩個參數it

從上往下透射率:

考慮到總體透射過去的光就是透射過第二塊玻璃的光,而因爲一部分光可能在兩塊玻璃間反射,因此透射過去的光分爲無窮多段,但最終的總和是收斂的(設第一塊玻璃透射率爲 \(a_1\),反射率爲 \(b_1\),第二塊玻璃透射率爲 \(a_2\),反射率爲 \(b_2\)):io

  • 第一束光:\(a_1a_2\)(直接透過兩塊玻璃)
  • 第二束光:\(a_1a_2b_1b_2\)(在兩塊玻璃間反射一個來回後透射出去)
  • 第三束光:\(a_1a_2(b_1b_2)^2\)(反射兩個來回)
  • ……

求和爲 \(\sum_{i=0}^{+\infty}a_1a_2(b_1b_2)^i=\frac {a_1a_2(1-(b_1b_2)^{+\infty})}{1-b_1b_2}\)class

因爲 \(b_1b_2<1\)反射

\[a'=\lim_{n\rightarrow +\infty}\frac {a_1a_2(1-(b_1b_2)^n)}{1-b_1b_2}=\frac {a_1a_2}{1-b_1b_2}\]方法

從下往上反射率:

相似於上面的方法:

  • 第一束光:\(b_2\)(直接反射)
  • 第二束光:\(a_2^2b_1\)(在第一塊玻璃反射一次,穿越兩次第二塊玻璃)
  • 第三束光:\(a_2^2b_1^2b_2\)(在中間多一個反射來回)

求和:

\[b'=b_2+\lim_{n\rightarrow +\infty}\frac {a_2^2b_1(1-(b_1b_2)^n)}{1-b_1b_2}=b_2+\frac {a_2^2b_1}{1-b_1b_2}\]

從上到下合併全部玻璃後最後一塊玻璃的透射率即爲答案

Code

#include <bits/stdc++.h>
typedef long long ll;

inline void read(int&x){
    char c11=getchar();x=0;while(!isdigit(c11))c11=getchar();
    while(isdigit(c11))x=x*10+c11-'0',c11=getchar();
}

const int p = 1e9+7, inv = 570000004;

inline int qpow(int A,int B) {
    int res = 1;
    while(B) {
        if(B&1) res = (ll)A * res%p;
        A = (ll)A * A%p, B >>= 1;
    } return res;
}

int n, a1, a2, b1, b2, a, b, iv;

int main() {
    read(n);
    read(a1), a1 = (ll)a1 * inv%p;
    read(b1), b1 = (ll)b1 * inv%p;
    while(--n) {
        read(a2), a2 = (ll)a2 * inv%p;
        read(b2), b2 = (ll)b2 * inv%p;
        iv = qpow(p+1 - (ll)b1 * b2%p, p-2);
        a = (ll)a1 * a2%p * iv%p;
        b = (b2 + (ll)a2 * a2%p * b1%p * iv)%p;
        a1 = a, b1 = b;
    }
    printf("%d\n",a1);
    return 0;
}
相關文章
相關標籤/搜索