[upcoj]6887: 遊戲

時間限制: 1 Sec 內存限制: 512 MB

題目描述

九條可憐是一個熱愛遊戲的女孩子,她經常在網上和一些網友們玩一款叫做《殭屍危機》遊戲。
在這款遊戲中,玩家們會需要在成爲殭屍之前與黑惡勢力鬥智鬥勇,逃離被病毒感染的小島。但是黑惡勢力不會讓玩家輕易得逞,他會把一些玩家抓走改造成殭屍。變成殭屍的玩家會攻擊其他的玩家,被攻擊的玩家會被”感染”,成爲病毒的潛在宿主。
具體來說,遊戲開始時,所有的玩家會獲得一個L∼R的編號(如果一共有R−L+1個玩家),不同的玩家的編號不同。
遊戲分輪次進行,在每一輪中一次會發生這樣的事情。
•如果所有當前所有的正常人都已經被感染,那麼遊戲結束。
•不然,黑惡勢力會在當前的正常人(包括被感染的人)中等概率隨機一個改造成殭屍。
•被改造成殭屍的玩家會攻擊所有編號是他的倍數的玩家,使得他們被感染。
九條可憐現在想知道,這個遊戲期望會進行多少輪?這個答案可能是一個實數,她想讓你給出期望輪數乘上(R−L+1)!以後的結果,這個結果可能很大,請對10^9+7取模後輸出。

輸入

第一行輸入兩個整數 L, R 表示編號範圍。

輸出

一個整數,表示期望進行的輪數。

樣例輸入

2 4

樣例輸出

16

提示

• 2 3 4, 輪數是 2。
• 3 2 4, 輪數是 2。
• 4 2 3, 輪數是 3。
• 4 3 2, 輪數是 3。
• 2 4 3, 輪數是 3。
• 3 4 2, 輪數是 3。
每種情況的概率都是 1/6,於是期望輪數就是 (2 + 2 + 3 + 3 + 3 + 3)/6 =8/3。
乘上 3! = 6 以後就是 16 。

對於 20% 的數據,R − L + 1 ≤ 8。
對於另 10% 的數據,L = 1。
對於另 10% 的數據,L = 2。
對於另 30% 的數據,L ≤ 200。
對於 100% 的數據,1 ≤ L ≤ R ≤ 107 。

來源/分類

江西OI2018

Solution

這是一道組合數學題。我覺得關鍵在於理解題意,細心分析。
對題意的補充說明和理解如下(感謝tb&&qg):
1.此處共有三類人,正常人、殭屍、被感染者;
2.成爲殭屍與被感染的不同之處 : 殭屍可以感染正常人,被感染者不能感染正常人,被感染者可以被改造成殭屍;
3.殭屍感染正常人不消耗時間;
4.遊戲只有在沒有1個正常人的時候才結束,例如樣例”2 4 3”是3輪——①選2改造成殭屍,同時2將4感染,3正常,遊戲不結束;②選4(已被感染)改造成殭屍,3仍正常,遊戲不結束;③3被改造成殭屍,沒有正常人了,遊戲結束。
重點在於用類似線性篩的方法求必須被改造的人數s,以及排列組合求ans。

Code

#include <cstdio>

const int MOD = 1000000007;
const int MX = 10000001;
int fac[MX];
long long tmp, ans;
bool vis[MX];
int l, r, n, s, p, i, j;

int main() {
    scanf("%d%d", &l, &r);
    fac[0] = fac[1] = 1;
    for (i = 2; i <= r; ++i) fac[i] = 1ll * fac[i - 1] * i % MOD;
    for (i = l; i <= r; ++i)
        if (!vis[i]) {
            s++;
            for (j = 1; j * i <= r; ++j) vis[j * i] = 1;
        }
    n = r - l + 1;
    tmp = 1;
    p = n - s;
    for (i = n; i >= s; --i) {
        ans = (ans + fac[i] * tmp) % MOD;
        (tmp *= p--) %= MOD;
    }
    (ans *= s) %= MOD;
    printf("%lld\n", ans);
    return 0;
}
/************************
    Time:392 ms
    Memory:49920 kb
*************************/
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章