• T48566 【zzy】yyy点餐


    T48566 【zzy】yyy点餐

    题目描述
    yyy去麦肯士吃垃圾食品。

    麦肯士有n种单点餐品(汉堡薯条鸡翅之类的)。每次选择一种或者以上的餐点,且每种餐点不多于一个的话,可以认为是购买套餐。购买一个套餐,价格是单品价格的总和(真黑啊),但是可以送一个玩具,yyy最喜欢麦肯士的玩具了。不过有规定即使多次购买同一种套餐(也就是里面的餐点的种类和数量完全一样)也只能获得一个玩具。

    yyy为了收集尽可能多的玩具,需要买尽可能多种的套餐。请问如果想要收集到最多的玩具数量,至少要花掉多少钱?由于yyy是个土豪,所以我们需要输出ans mod 998244353的结果。

    说明
    【样例解释】

    1 / 2 / 3 / 4 / 5
    12 / 13 / 14 / 15
    23 / 24 / 25
    34 / 35 / 45/ 
    123 / 124 / 125 / 134 / 135 / 145
    234 / 235 / 245
    345
    1234 / 1235 / 1245 / 1345 / 2345
    12345
    

    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} * 5sum_{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} * nsum_{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
    ", tot * Q_pow(2, num - 1, M) % M);
    	return 0;
    	}
    
  • 相关阅读:
    Best Time to Buy and Sell Stock II
    Subsets II
    Subsets I
    Combinations
    Permutation Sequence
    Next Permutation
    Anagrams
    Combination-Sum II
    Combination-Sum I
    Permutations II
  • 原文地址:https://www.cnblogs.com/Tony-Double-Sky/p/9799865.html
Copyright © 2020-2023  润新知