CodeChef--Cards, bags and coins
Yet another game from chef. Chef gives you N cards and M bags. Each of the N cards has an integer written on it. Now chef asks you to close your eyes and choose a subset of them. He then sums the numbers written on chosen cards, takes its absolute value and gives you those many coins. You win the game if you can divide these coins into M bags with each bag having equal share. As a first step to calculate the probability of winning, you would like to know the number of different subsets which will make you win. Note that all the cards are of different color, so even if 2 cards have the same number written on it, they are still considered as different cards.
Input
The first line of the input contains an integer T denoting the number of test cases. The description of T test cases follows.
First line of each test case contains two integers N and Q. Q denotes the number of queries to be answered. Second line of each test case contains N integers, the numbers written on cards.
Following Q lines contain an integer M.Output
For each query output the required Answer modulo 1000000009. Answer is the number of subsets that will ensure you win.
Constraints
- 1 ≤ T ≤ 3
- 1 ≤ N ≤ 100000
- 1 ≤ Q ≤ 30
- 1 ≤ M ≤ 100
- -10^9 ≤ Number on card ≤ 10^9
Example
Input
2
5 1
1 2 -1 4 5
9
5 2
1 2 3 4 5
5
15 Output
4
8
2Explanation
Test Case #1, Query #1
{}, {1,-1}, {1,-1,4,5}, {4,5} are winning subsets. Sums are 0, 0, 9, 9 respectively.Test Case #2, Query #1
{}, {5}, {1,4}, {2,3}, {1,4,5}, {2,3,5}, {1,2,3,4}, {1,2,3,4,5} are winning subsets. Sums are 0, 5, 5, 5, 10, 10, 10, 15 respectively.Test Case #2, Query #2
{}, {1,2,3,4,5} are winning subsets. Sums are 0 and 15 respectively.Author's Note
Time Limit is not very strict (Yes, not very loose either) if correct Algorithm is used.Author's solution passes with 2 sec Time Limit (C++ solution, using scanf and printf).
Maximum Input File Size < 4MB.
题意:给出n个数,然后还有一个数字m,问有多少种方法可以从n个数中选出一些数使得这些数的和是m的倍数。
很好的一道题,学到了很多。首先对于自己的基础之差感动汗颜。
第一,对C(n, k)的打表。。。这里还是说下自己的想法吧,如果n<10^3,这个数据量基本是可以用递推的,二维数组C[n][k]记录。
像这题的n<10^5,显然无法开出巨表,所以可以使用C(n, k) = n!/(k! * (n -k)!)..这样就可以通过记录n!和n!的逆来进行求解,
如果题目给出的模数是个质数,就可以通过费马小定理很方便的求出一个数的逆元,当然扩展gcd也是可以的。
其次,对于这题的思路,看到题目和数据范围就应该想到实际上真正的数据范围就只有[0, m)...所以每次询问直接将A[i]模m,然后
得到每个数出现的次数。这样就可以得到dp的基本模型了。
dp[i][j]表示从0到i这些数中选一些数模m为j的方案数,然后dp[i][j]可以从dp[i-1][0..m-1]得到。
Accepted Code:
/*************************************************************************
> File Name: ANUCBC.cpp
> Author: Stomach_ache
> Mail: sudaweitong@gmail.com
> Created Time: 2014年09月04日 星期四 14时13分00秒
> Propose:
************************************************************************/
#include <cmath>
#include <string>
#include <cstdio>
#include <fstream>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
/*Let's fight!!!*/ #define rep(i, n) for (int i = (0); i < (n); i++)
#define FOR(i, a, b) for (int i = (a); i <= (b); i++)
const int MAX_N = ;
const int MAX_M = ;
const int MOD = 1e9 + ;
typedef long long LL;
LL fact[MAX_N], ifact[MAX_N]; LL pow_mod(LL a, LL b) {
LL res = ;
while (b) {
if (b & ) res = (res * a) % MOD;
a = (a * a) % MOD;
b >>= ;
}
return res;
} //fact and ifact
void init() {
fact[] = fact[] = ifact[] = ifact[] = ;
FOR (i, , MAX_N - ) {
fact[i] = (fact[i - ] * i) % MOD;
ifact[i] = (ifact[i - ] * pow_mod(i, MOD - )) % MOD;
}
} int C(int n, int k) {
return (fact[n] * ifact[k] % MOD) * ifact[n - k] % MOD;
} int A[MAX_N], cnt[MAX_M];
LL dp[MAX_M][MAX_M], choose[MAX_M][MAX_M]; int main(void) {
init(); // precomputation ios::sync_with_stdio(false);
int T;
cin >> T;
while (T--) {
int N, Q, M;
cin >> N >> Q;
rep (i, N) cin >> A[i];
while (Q--) {
cin >> M;
memset(cnt, , sizeof(cnt));
rep (i, N) cnt[(A[i] % M + M) % M]++; memset(choose, , sizeof(choose));
rep (i, M) FOR (j, , cnt[i]) {
choose[i][j * i % M] = (choose[i][j * i % M] + C(cnt[i], j)) % MOD;
} memset(dp, , sizeof(dp));
dp[][] = choose[][];
FOR (i, , M-) rep (j, M) rep (k, M) dp[i][j] = (dp[i][j] + dp[i - ][(j - k + M) % M] * choose[i][k]) % MOD; cout << dp[M - ][] << endl;
}
}
return ;
}
CodeChef--Cards, bags and coins的更多相关文章
- CodeChef Cards, bags and coins [DP 泛型背包]
https://www.codechef.com/problems/ANUCBC n个数字,选出其一个子集.求有多少子集满足其中数字之和是m的倍数.n $\le$ 100000,m $\le$ 100 ...
- [CC-ANUCBC]Cards, bags and coins
[CC-ANUCBC]Cards, bags and coins 题目大意: 给你\(n(n\le10^5)\)个数,\(q(q\le30)\)次询问,问从中选取若干个数使得这些数之和为\(m(m\l ...
- Codechef APRIL14 ANUCBC Cards, bags and coins 背包DP变形
题目大意 有n个数字,选出一个子集,有q个询问,求子集和模m等于0的方案数%1000000009.(n <= 100000,m <= 100,q <= 30) 假设数据很小,我们完全 ...
- Codeforces Round #207 (Div. 1) D - Bags and Coins 构造 + bitset优化dp + 分段查找优化空间
D - Bags and Coins 思路:我们可以这样构造,最大的那个肯定是作为以一个树根,所以我们只要找到一个序列a1 + a2 + a3 .... + ak 并且ak为 所有点中最大的那个,那么 ...
- [CodeForce]356D Bags and Coins
已知有n个包,和总共s个钱币. n,s<=70000. 每个包可以装钱币,还可以套别的包.每个包中的钱数等于 所有套的包的钱数 加上 自己装的钱. 所有的钱都在包内. 问给定每个包中的钱数,输出 ...
- 贪心/构造/DP 杂题选做Ⅲ
颓!颓!颓!(bushi 前传: 贪心/构造/DP 杂题选做 贪心/构造/DP 杂题选做Ⅱ 51. CF758E Broken Tree 讲个笑话,这道题是 11.3 模拟赛的 T2,模拟赛里那道题的 ...
- CodeChef:Little Elephant and Colored Coins
类似墨墨的等式 设f[2][j][k]表示a[i].c是否和当前颜色相同,到当前枚举到的颜色为止,颜色数为j,对mnv取模为k的最小数 这是个无限循环背包,用spfa优化 #include<cs ...
- PAT 甲级 1068 Find More Coins (30 分) (dp,01背包问题记录最佳选择方案)***
1068 Find More Coins (30 分) Eva loves to collect coins from all over the universe, including some ...
- BZOJ 1004 【HNOI2008】 Cards
题目链接:Cards 听说这道题是染色问题的入门题,于是就去学了一下\(Bunside\)引理和\(P\acute{o}lya\)定理(其实还是没有懂),回来写这道题. 由于题目中保证"任意 ...
随机推荐
- 【颓废篇】人生苦短,我用python(一)
谁渴望来一场华(ang)丽(zang)的python交易! 最近突然产生了系统学习python的想法. 其实自从上次luogu冬日绘板dalao们都在写脚本就有这种想法了. 最近被计算几何势力干翻的我 ...
- 转:浅析C++中的this指针
原文出处:http://blog.csdn.net/starlee/article/details/2062586 有下面的一个简单的类: class CNullPointCall { public: ...
- It's a Mod, Mod, Mod, Mod World (类欧几里得模板题
https://vjudge.net/contest/317000#problem/F #include <iostream> #include <cstdio> #inclu ...
- 【JZOJ3379】查询
description 对于一个整数序列,查询区间第k大数可以在O(logN)的时间内轻松完成.现在我们对这个问题进行推广. 考虑带重复数的集合(multiset).定义在该类集合上的并操作" ...
- 爆表!猜猜这个大会的IQ总值有多高?
“人人可及的未来,同样存在于「日拱一卒」的琐碎生活当中,那也是技术对生活最为直观的改变和演进.” “以通神明之德,以类万物之情”,这句来自<易经>的话,放到现今也合宜. 人类掌控事物发展的 ...
- 【Codeforces Round #424 (Div. 2) D】Office Keys
[Link]:http://codeforces.com/contest/831/problem/D [Description] 有n个人,它们都要去一个终点,终点位于p; 但是,在去终点之前,他们都 ...
- c语言学习笔记 - 文件操作
#include <stdio.h>#include <time.h> int main(void){ time_t t; //类似于size_t那 ...
- CSS或HTML如何实现文字下面加点?
就像word里文字加着重号一样,在字的下面加一个点,用CSS怎么做?注意,我说的是下面加点,不是文字加粗或倾斜,请不要回答<strong>或<em>之类的. 把要着重加点的文字 ...
- ES6之主要知识点(一)
引自:http://es6.ruanyifeng.com let 块级作用域 const 1.let let声明的变量只在它所在的代码块有效. for循环的计数器,就很合适使用let命令. var a ...
- intellij idea中去除@Autowired注入对象带来的下划线提示
场景: idea中通过@Autowired注入的对象一直有下划线提示,虽然不影响运行 解决:改变@Autowired的检查级别即可. 快捷键:Ctrl+Alt+s,进入idea设置界面,输入inspe ...