CTSC2018 假面 期望 DP

2022-03-30 05:42:37 字數 1512 閱讀 3297

loj 2552

luogu p4564

考場上這道題我先是寫了個70分暴力,然後發現似乎可以ntt,然鵝問題是——我沒學過ntt,遂腦補之,腦補出來了,下午出成績一看,卡成暴力分(70)……同是\(o(qk^2\log k)\),學姐的拉格朗日什麼玩意就能過tat……學姐太強了……

遂不忿,今天上午重寫ntt,努力卡常,卡不進去……

那還是寫正解吧。

首先,發現血量上限很少,0操作時,暴力維護每一時刻每個人是每種血量大小的概率即可。

1操作怎麼辦呢?設\(alive_i\)是\(i\)號人活著的概率,\(dead_i\)是他死了的概率,\(g_\)是除\(i\)以外活了\(j\)個人的概率,\(i\)號人的答案就是$$alive_i * \sum_^\frac * g_$$

但是\(g_\)怎麼求呢?發現可以dp:設\(f_\)表示前\(i\)個人有\(j\)個活著的概率,則$$f_ = f_ * dead_i + f_ * alive_i$$

注意到最後的\(f\)和人的順序無關,所以可以把人的順序任意調換,把要求的這個\(i\)放在最後乙個,這樣\(f_\)就是\(g_\)。

那麼對於每個\(i\)求一遍\(f\),複雜度是\(o(n^3)\)的,能得70分。

如何優化呢?考慮把\(i\)號人放在最後時,從\(f_k\)倒推到\(f_\):$$\frac = f_ - f_ * alive_i}$$

注意到\(dead_i = 0\)時該式不能用,又發現此時\(f_ = f_\),所以也能直接求。

那麼\(o(n^2)\)求出\(f_k\),再\(o(n^2)\)倒推,直接可以獲得答案!

#include #include #include #include #include #define space putchar(' ')

#define enter putchar('\n')

typedef long long ll;

using namespace std;

template void read(t &x)

template void write(t x)

const int n = 256, p = 998244353;

int n, m, k, t[n], b[n], rate[n][105], iv[n];

ll qpow(ll a, ll x)

return ret;

}void attack(int tar, ll x)

}void query()

} h[i] %= p;

h[i] = h[i] * (1 - rate[t[i]][0]) % p;

if(h[i] < 0) h[i] += p;

}for(int i = 1; i <= k; i++)

write(h[i]), i == k ? enter: space;

}int main()

}for(int i = 1; i <= n; i++)

return 0;

}

CTSC2018 假面 01揹包的刪除

首先記錄ai ja i,j表示單位 i i 生命值為 j role presentation style position relative j j的概率,那麼每次修改可以o m o m 對於詢問,先求出ex i m ij 1 ai,j e xi j 1mia i,j表示單位 i i 存活的概率。那...

CTSC2018 混合果汁

為何要用整體二分,整體二分應該怎樣二分,和 poi2011 met meteors十分相像,這裡就不再重複。那麼對於乙個顧客來講,如果當前的區間總份數小於他想要的份數,或者是區間最小 大於他能接受的最大 就把該顧客劃分到右區間,如若滿足則劃分到左區間。想要和 poi2011 met meteors一...

CTSC 2018 混合果汁

題目鏈結 演算法 對於每組詢問 首先二分答案 顯然 最優策略為優先選擇 低的 建立可持久化線段樹 簡單維護即可 時間複雜度 o nlogn 2 includeusing namespace std define n 100010typedef long long ll typedef long do...