同余+最短路 做完全背包

POI X Sums

 

 

一个集合 SSS 内有 nnn 个正整数 {a1,a2,…,an}\{a_1, a_2, \ldots, a_n\}{a​1​​,a​2​​,…,a​n​​}S′S'S​′​​ 表示由集合 SSS 中的数相加所得的集合,每个数都可以用无数次。

qqq 次询问,询问一个 xxx 是否在 S′S'S​′​​ 内。存在输出 y 否则输出 n

n≤5000,q,ai,≤50000,x≤1017n \leq 5000, q, a_i, \leq 50000, x \leq 10^{17}n≤5000,q,a​i​​,≤50000,x≤10​17​​.

输入 nnn ,然后输入 nnn 个数,再输入 qqq,然后qqqxxx

 

题意可以转化为:给定a数组,问式子a[1]*x[1]+a[2]*x[2]+……+a[n]*x[n]=k是否有正整数解。

其实看下来,这就是一个容量为k的完全背包,判断是否能恰好装满。

叉姐的解释:

 

 

SSS 中找一个数,例如 a1a_1a​1​​. 一个关键性质是:如果 x∈S′x \in S'x∈S​′​​,那么x+a1∈S′x + a_1 \in S'x+a​1​​∈S​′​​.

那么设 d[r]d[r]d[r] 表示所有模 a1a_1a​1​​rrr 的数中,最小的 ∈S′\in S'∈S​′​​ 的数。根据性质,d[r],d[r]+a1,d[r]+2a1,…∈S′d[r], d[r] + a_1, d[r] + 2a_1, \ldots \in S'd[r],d[r]+a​1​​,d[r]+2a​1​​,…∈S​′​​. 同时因为 d[r]d[r]d[r] 是最小的,所以同余类中 <d[r]< d[r]<d[r] 的数都 ∉S′\notin S'∉S​′​​.

具体求 d[∗]d[*]d[∗] 的过程是最短路。首先,d[0]=0d[0] = 0d[0]=0。其次,可以用d[x]+aid[x] + a_id[x]+a​i​​ 去更新 d[(x+ai) mod a1]d[(x + a_i)\ \mathrm{mod}\ a_1]d[(x+a​i​​) mod a​1​​].
这里如果用 Dijkstra 的话,复杂度是 O(na1loga1)O(na_1 \log{a_1}). 从这个角度上讲,

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值