zoukankan      html  css  js  c++  java
  • [HAOI2018]奇怪的背包

    题目链接

    题目大意

    有一个模P意义下的背包,n个物品,每种有无限个,q个询问,问重量为w的方案。
    题解:
    首先,先考虑如何判断一些物品能否组成重w的背包。
    根据贝祖定理,只要这些数和P的最大公约数是w的约数,就可以。

    所以,对于本题,就是判断(2^n)中方案中,有多少种方案使得选择的数和P的最大公约数是w的约数。
    显然,有一个(O((n+q)*约数个数))的dp,会超时。

    考虑优化:
    对于询问,枚举w的约数x,根据之前的分析,只有x是P的约数才有解。
    所以,枚举(gcd(w,P))的约数即可。
    由于P的约数不多,所以可以枚举P的约数y,预处理(gcd(w,P)=y)时的答案。
    对于DP个过程,也可以用类似的方法:
    由于要和P取gcd,所以每个V与(gcd(V,P))等价,而不同的(gcd(V,P))只有(O(P的约数个数))个。
    这样,枚举(gcd(V,P))进行DP,就行了。
    由于要用map定位约数,时间复杂度为(O(M^2logM+(n+q)logP)),能过。(M为P的约数个数)

    代码

    #include <stdio.h> 
    #include <map> 
    using namespace std;
    #define md 1000000007 
    map < int,int > mp;
    int gcd(int a, int b) {
    	while (b != 0) {
    		int t = a % b;
    		a = b;
    		b = t;
    	}
    	return a;
    }
    int ys[1500],m = 0,dp[1500][1500],sl[1500],mi[1000010],ans[1500];
    int main() {
    	int n,q,P;
    	scanf("%d%d%d", &n, &q, &P);
    	for (int i = 1; 1ll * i * i <= P; i++) {
    		if (P % i == 0) {
    			ys[m++] = i;
    			if (P / i != i) ys[m++] = P / i;
    		}
    	}
    	for (int i = 0; i < m; i++) mp[ys[i]] = i;
    	for (int i = 0; i < n; i++) {
    		int a;
    		scanf("%d", &a);
    		sl[mp[gcd(P, a)]] += 1;
    	}
    	mi[0] = 1;
    	for (int i = 1; i <= n; i++) mi[i] = (mi[i - 1] + mi[i - 1]) % md;
    	dp[0][1] = 1;
    	for (int i = 0; i < m; i++) {
    		for (int j = 0; j < m; j++) {
    			dp[i + 1][j] = (dp[i + 1][j] + dp[i][j]) % md;
    			int t = mp[gcd(ys[j], ys[i])];
    			dp[i + 1][t] = (dp[i + 1][t] + 1ll * (mi[sl[i]] - 1 + md) * dp[i][j]) % md;
    		}
    	}
    	for (int i = 0; i < m; i++) {
    		for (int j = 0; j < m; j++) {
    			if (ys[i] % ys[j] == 0) ans[i] = (ans[i] + dp[m][j]) % md;
    		}
    	}
    	for (int i = 0; i < q; i++) {
    		int a;
    		scanf("%d", &a);
    		printf("%d
    ", ans[mp[gcd(a, P)]]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    结巴分词 0.14 版发布,Python 中文分词库
    Lazarus 1.0.2 发布,Pascal 集成开发环境
    Android全屏 去除标题栏和状态栏
    服务器日志现 Android 4.2 传将添多项新特性
    Percona XtraBackup 2.0.3 发布
    长平狐 Android 强制设置横屏或竖屏 设置全屏
    NetBeans 7.3 Beta 发布,全新的 HTML5 支持
    CppDepend现在已经支持Linux
    GromJS 1.7.18 发布,服务器端的 JavaScript
    Apache OpenWebBeans 1.1.6 发布
  • 原文地址:https://www.cnblogs.com/lnzwz/p/11354673.html
Copyright © 2011-2022 走看看