T48566 【zzy】yyy点餐
T48566 【zzy】yyy點餐
題目描述
yyy去麥肯士吃垃圾食品。
麥肯士有n種單點餐品(漢堡薯條雞翅之類的)。每次選擇一種或者以上的餐點,且每種餐點不多于一個的話,可以認為是購買套餐。購買一個套餐,價格是單品價格的總和(真黑啊),但是可以送一個玩具,yyy最喜歡麥肯士的玩具了。不過有規定即使多次購買同一種套餐(也就是里面的餐點的種類和數量完全一樣)也只能獲得一個玩具。
yyy為了收集盡可能多的玩具,需要買盡可能多種的套餐。請問如果想要收集到最多的玩具數量,至少要花掉多少錢?由于yyy是個土豪,所以我們需要輸出ans mod 998244353的結果。
說明
【樣例解釋】
1≤n≤1000000
錯誤日志: 輸出的時候忘記模了QAQ
Solution
設 \(tot\) 為所有單點餐品的總花費和
顯然當套餐內單品數量為 \(k\) 時, 這一組套餐總共會花費 \(C_{n}^{k} * k * tot * \frac{1}{n}\)
那么總答案即為:
\[ans = tot * \frac{1}{n}\sum_{k = 1}^{n}C_{n}^{k} * k\]
組合數可以用二項式定理展開求得, 難搞的是每一項要乘個 \(k\)
于是嘗試把 \(k\) 弄出來
\[\sum_{k = 1}^{n}C_{n}^{k} * k\]\[=\sum_{k = 1}^{n}C_{n}^{k} * k + 0\]\[=\sum_{k = 1}^{n}C_{n}^{k} * k + C_{n}^{1} * 0\]\[=\sum_{k = 0}^{n}C_{n}^{k} * k\]
通式不好說明, 以 \(n = 5\) 為例:
\[\sum_{k = 0}^{5}C_{5}^{k} * k\]\[= C_{5}^{0} * 0 + C_{5}^{1} * 1 + C_{5}^{2} * 2 + C_{5}^{3} * 3 + C_{5}^{4} * 4 + C_{5}^{5} * 5\]\[=\frac{1}{2}(C_{5}^{0} * 0 + C_{5}^{0} * 0 + C_{5}^{1} * 1 + C_{5}^{1} * 1 + C_{5}^{2} * 2 + C_{5}^{2} * 2 + C_{5}^{3} * 3 + C_{5}^{3} * 3 + C_{5}^{4} * 4 + C_{5}^{4} * 4 + C_{5}^{5} * 5 + C_{5}^{5} * 5)\]\[=\frac{1}{2}(C_{5}^{0} * 0 + C_{5}^{5} * 5 + C_{5}^{1} * 1 + C_{5}^{4} * 4 + ... + C_{5}^{5} * 5 + C_{5}^{0} * 0)\]\[=\frac{1}{2} * 5\sum_{k = 0}^{5}C_{5}^{k}\]
將此式帶入總答案式, 用通式加二項式定理表達為:
\[ans = tot * \frac{1}{n}\sum_{k = 0}^{n}C_{n}^{k} * k\]\[=tot * \frac{1}{n} * \frac{1}{2} * n\sum_{k = 0}^{n}C_{n}^{k}\]\[ = tot * \frac{1}{2} * 2^{n}\]\[=tot * 2^{n - 1}\]
快速冪即可
Code
#include<iostream> #include<cstdio> #include<queue> #include<cstring> #include<algorithm> #include<climits> #define LL long long #define REP(i, x, y) for(LL i = (x);i <= (y);i++) using namespace std; LL RD(){LL out = 0,flag = 1;char c = getchar();while(c < '0' || c >'9'){if(c == '-')flag = -1;c = getchar();}while(c >= '0' && c <= '9'){out = out * 10 + c - '0';c = getchar();}return flag * out;} const LL M = 998244353; LL num, tot; LL Q_pow(LL a, LL p, LL mod){LL ret = 1;while(p){if(p & 1)ret = ret * a % mod;a = a * a % mod;p >>= 1;}return ret;} int main(){num = RD();REP(i, 1, num)tot = (tot + RD()) % M;printf("%lld\n", tot * Q_pow(2, num - 1, M) % M);return 0;}轉載于:https://www.cnblogs.com/Tony-Double-Sky/p/9799865.html
總結
以上是生活随笔為你收集整理的T48566 【zzy】yyy点餐的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: p2p网络实现(C++)
- 下一篇: 地下水情监测仪应用库区安全行业