【BZOJ5302】[HAOI2018]奇怪的背包(动态规划,容斥原理)

题面

BZOJ

洛谷

题解

为啥泥萌做法和我都不一样啊

一个重量为\(V_i\)的物品,可以放出所有\(gcd(V_i,P)\)的重量,而多个物品也只要\(gcd\)就好了。

现在的问题转变成了有多少个集合\(S\),满足\(S+\{P\}\)中所有数的\(gcd\)是\(w\)的因数。那么实际上就是直接令\(a[i]'=gcd(a[i],P)\),然后选出一个集合使得它是\(gcd(P,w)\)的因数。

考虑对于\(P\)的每个因数预处理答案,不记得在哪里看到的,当\(P\)较大的时候,其约数个数是\(P^{\frac{1}{3}}\)级别,那么在这里就可以暴力把所有因数算出来之后\(O(\sigma^2)\)计算,即先统计有多少个\(a[i]'\)是当前\(d\)的倍数,那么贡献是\(2^{s}-1\),然后容斥减去所有\(d\)的倍数的答案就是\(gcd\)为\(d\)的答案。然后再\(O(\sigma^2)\)的计算约数和就好了。

这样子复杂度大概是\(O((n+Q)logP+\sigma(P)^2)\),前面那个\(log\)来自于\(gcd\)的复杂度。

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define MOD 1000000007
#define MAX 1000100
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
int n,Q,P,a[MAX],bin[MAX];
const int blk=50000;
int w[blk],tot,id1[blk],id2[blk],f[blk],s[blk];
int ID(int x){return x<blk?id1[x]:id2[P/x];}
int S[blk],top;
int main()
{
n=read();Q=read();P=read();
for(int i=1;i<=n;++i)a[i]=__gcd(read(),P);
bin[0]=1;for(int i=1;i<=n;++i)bin[i]=(bin[i-1]<<1)%MOD;
for(int i=1;i*i<=P;++i)
if(P%i==0)
{
w[++tot]=i;
if(P/i!=i)w[++tot]=P/i;
}
sort(&w[1],&w[tot+1]);
for(int i=1;i<=tot;++i)
if(w[i]<blk)id1[w[i]]=i;
else id2[P/w[i]]=i;
for(int i=1;i<=n;++i)s[ID(a[i])]+=1;
for(int i=tot;i;--i)
{
int cnt=0;top=0;
for(int j=i;j<=tot;++j)
if(w[j]%w[i]==0)S[++top]=j,cnt+=s[j];
f[i]=bin[cnt]-1;
for(int j=2;j<=top;++j)f[i]=(f[i]+MOD-f[S[j]])%MOD;
}
for(int i=tot;i;--i)
for(int j=1;j<i;++j)
if(w[i]%w[j]==0)f[i]=(f[i]+f[j])%MOD;
while(Q--)
{
int d=__gcd(read(),P);
printf("%d\n",f[ID(d)]);
}
return 0;
}

【BZOJ5302】[HAOI2018]奇怪的背包(动态规划,容斥原理)的更多相关文章

  1. BZOJ5302: [Haoi2018]奇怪的背包

    BZOJ5302: [Haoi2018]奇怪的背包 https://lydsy.com/JudgeOnline/problem.php?id=5302 分析: 方程\(\sum\limits_{i=1 ...

  2. BZOJ5302 [HAOI2018]奇怪的背包 【数论 + dp】

    题目 小 CC 非常擅长背包问题,他有一个奇怪的背包,这个背包有一个参数 PP ,当他 向这个背包内放入若干个物品后,背包的重量是物品总体积对 PP 取模后的结果. 现在小 CC 有 nn 种体积不同 ...

  3. BZOJ5302 HAOI2018奇怪的背包(动态规划)

    由裴蜀定理,子集S有解当且仅当gcd(S,P)|w. 一个显然的dp是设f[i][j]为前i个数gcd为j的选取方案.注意到这里的gcd一定是P的约数,所以状态数是n√P的.然后可以通过这个得到gcd ...

  4. [BZOJ5302][HAOI2018]奇怪的背包(DP)

    由裴蜀定理得,一个集合S能得到w当且仅当gcd(S+{P})|w. 于是f[i][j]表示前i个物品gcd为j的方案数,发现gcd一定是P的因数,故总复杂度$O(n\sqrt{P}\log P)$(需 ...

  5. [HAOI2018]奇怪的背包 (DP,数论)

    [HAOI2018]奇怪的背包 \(solution:\) 首先,这一道题目的描述很像完全背包,但它所说的背包总重量是在模P意义下的,所以肯定会用到数论.我们先分析一下,每一个物品可以放无数次,可以达 ...

  6. 洛谷 P4495 [HAOI2018]奇怪的背包 解题报告

    P4495 [HAOI2018]奇怪的背包 题目描述 小\(C\)非常擅长背包问题,他有一个奇怪的背包,这个背包有一个参数\(P\),当他 向这个背包内放入若干个物品后,背包的重量是物品总体积对\(P ...

  7. haoi2018奇怪的背包题解

    题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=5302 对于一个物品,设它体积为v,那么,在背包参数为p的情况下,它能达到gcd(v,p ...

  8. bzoj 5302: [Haoi2018]奇怪的背包

    Description Solution 首先 \(v_1,v_2,v_3...v_n,P\) 能够构成的最小数是 \(gcd(P,v_1,v_2,v_3...v_n)\) 然后 \(gcd(P,v_ ...

  9. Luogu4495 [HAOI2018] 奇怪的背包 【扩展欧几里得算法】

    题目分析: 首先打个暴力求一下$10^9$以内因子最多的数的因子个数,发现只有$1344$个. 由于有$ax+by=k*(a,b)$和2017年noip的结论,所以我们可以发现对于任意多个数$a_1, ...

随机推荐

  1. Python_生产者消费者模型、管道、数据共享、进程池

    1.生产者消费者模型 生产者 —— 生产数据的人 消费者 —— 消费数据的人 生产者消费者模型:供销数据不平衡的现象. import time import random from multiproc ...

  2. Django的contenttypes

    这是一个django内置的表结构,为的就是通过两个字段让表和N张表创建FK关系. 比如说有两种不同课程,这两种课程都有价格周期和策略.如果最低级的则是给每个表创建一个价格策略.如果非要在同一个表内使用 ...

  3. Python之操作redis数据库

    使用redis模块 一.操作redis 1.添加信息 (1)直接建key-value信息: 右键-Add New Key,手动添加key和value 右键-Console,打开控制台,写入命令 (2) ...

  4. redis 运维手册

    redis cli命令 - milkty - 博客园https://www.cnblogs.com/kongzhongqijing/p/6867960.html Redis多个数据库 - EasonJ ...

  5. AJAX返回值问题

    ajax同步方式获取返回值,必须以同步请求的的方式获取. //主函数部分 function confirm(id,...)//省略部分参数 { //...省略部分代码 //任务涉及专业 var Maj ...

  6. [转帖]NUMA

    作者:ibless 来源:CSDN 原文:https://blog.csdn.net/ibless/article/details/80114009 其实 很早之前对这一块有了解 比较多的的是 CCN ...

  7. python爬虫之git的使用(coding.net的使用)

    1.注册coding.net账号,然后登陆. 2.创建项目 套路和github都一样. 1.1.我们在远程仓库上创建了一个仓库,这样的话,我们需要在本地随便建立一个文件普通文件夹,进去以后,执行git ...

  8. Django--ORM 多表查询

    一 . 建立外键 一对一建立外键 外键名称 = models.OneToOneField(to='要连接的类名', to_field='字段') 一对多建立外键 外键名称 = models.Forei ...

  9. 常用Mac快捷键

    1.复制Cmd + C 粘贴Cmd + C —-> Cmd + V 剪切Cmd + C —-> Cmd + Opt + V 2.查看隐藏文件 Cmd + shift + . 3. 货币符号 ...

  10. orcale建表脚本

    declare v_cnt number; V_SQL VARCHAR2 (500) := '';begin select count(*) into v_cnt from dual where ex ...