给定 n 个正整数序列 ,每个序列长度为m。

选择至少 1 个序列,在每个被选择的序列中选择一个元素,求出所有被选择的元素的 gcd。

求所有方案的结果之和,答案对 1e9+7 取模。两种方案不同,当且仅当存在至少一个元素,在一种方案中被选择,在另一种中没有。

這道題看n=20 m=1e5的範圍就知道不可能進行枚舉算法

枚舉是O(m^n)的,一定會tle,得想更加快速的方法

在計數問題中,我們經常會想到容斥原理

而且這道題的數範圍也只有1e5,我們應該想到按照每一個數的值來計算答案

在這道題之中,計算出“每一行能夠不選或只選1個數,但是必須至少選1個數,要求這些選出來的數被k整除”很容易。只要計cnt[i][j]表示第i行有多少個數是j的倍數。

如何求cnt數組,我們可以記錄cnt[i][j],將cnt[i][a[i][j]]全部+1,代表現在,我們已經存儲了a[i][j]被自己整除的方案了

現在我們知道,當一個數是ak的倍數時,這個數同時也是a的倍數,所以我們可以知道,f[i][kj]可以用來更新f[i][j]。

則ans=(cnt[1][k]+1)(cnt[2][k]+1)…(cnt[n][k]+1)-1

在這道題中,一行有cnt[i][k]個數可以選擇,而且這一行可以一個數都不選,有cnt[i][k]+1種方案,全部乘起來就是答案

但是,我們還有可能一個數都沒有選,這種情況計算了進去,所以最後的方案要-1

在這道題中,我們也可以想到類似的思路

記ans[k]表示全局選出的數能夠被k整除的方案數

則ans[k]=(cnt[1][k]+1)
(cnt[2][k]+1)…(cnt[n][k]+1)-1

用這個公式可以快速計算出所有的ans

但是,這道題要求求的是gcd==k的個數,這個公式不能滿足要求

因為我們選出的方案中,只代表gcd能夠被k整除,而不可以代表“gcd恰好為k的方案數"

實際上,我們還計算出了gcd為2k,gcd為3k等等的方案數,所以我們需要將其減去

設f[i]表示gcd恰好為i的方案數

則f[i]=ans[i]-f[2i]-f[3i]…-f[(n/i)i]

式子的前一項為"gcd被i整除"的方案數,但是我們不需要gcd為2
i,3i…的方案,所以我們在後面將它們減去了。而在這個方程之中,我們可以倒序枚舉i,這樣我們可以保證計算出f[i]前,f[2i],f[3*i]…已經計算出來了

最後,由於題目要求,我們要記錄gcd的和,所以我們要求f[1]*1,f[2]*2…的值

這樣,我們就成功解決了本題

jzoj5843的更多相关文章

随机推荐

  1. [Git]Git的常用命令

    Update: git status git diff wq git commit -am "why update files" git push Add: git add . g ...

  2. centos6.5 设置ssh无密码登录

    :关闭防火墙 vim /etc/selinux/config 把SELINUX=enforcing修改为SELINUX=disabled   A机器root连接B机器root用户 (root用户登录) ...

  3. attempt to create delete event with null entity

    解决办法:删除之前判断是否为空 if(Object != null){ session.delete(Object); }

  4. 2018.10.18 bzoj4105: [Thu Summer Camp 2015]平方运算(线段树)

    传送门 线段树妙题. 显然平方几次就会循环(打表证明不解释). 然后所有环长度的lcmlcmlcm不大于70. 因此维护一下当前区间中的节点是否全部在环上. 不是直接暴力到叶子节点修改. 否则整体打标 ...

  5. 2018.08.27 rollcall(非旋treap)

    描述 初始有一个空集,依次插入N个数Ai.有M次询问Bj,表示询问第Bj个数加入集合后的排名为j的数是多少 输入 第一行是两个整数N,M 接下来一行有N个整数,Ai 接下来一行有M个整数Bj,保证数据 ...

  6. BZOJ 1003 物流运输 (dp + dijkstra)

    1003: [ZJOI2006]物流运输 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 8672  Solved: 3678[Submit][Stat ...

  7. 通过hbase实现日志的转存(MR AnalyserLogDataRunner和AnalyserLogDataMapper)

    操作代码(提前启动集群(start-all.sh).zookeeper(zkServer.sh start).启动历史任务服务器(mr-jobhistory-daemon.sh start histo ...

  8. java学习之路-分享笔记20150327

    ---恢复内容开始--- 2个月间,断断续续学习了一段时间java平台相关知识,慢慢梳理出来一些枝枝叶叶,和大家交流下.3年前用java边看边做写了一个项目,所以对语法不是很关注.需要原文档的留邮箱吧 ...

  9. SPFA穿越虫洞——负权回路得判断

    poj3259 题目大意:穿越虫洞可以回到过去(时间--)所以能不能让时间倒流呢,就是判断有没有负权回路这次尝试用SPFA算法,也可以复习一下链式前向星 准备工作,队列q,spfa算法得有点就在于这个 ...

  10. [诈骗]“中国移动”发送诈骗短信,china mobile 是骗子吗?

    今年,这是我遇到的第二次短信诈骗了,两次的手法都是完全一样的.第一次,冒充的是招商银行的积分活动,结果我还真的输入了银行卡与取款密码. 输入完之后,我才醒悟,然后立刻打招商客服电话咨询,改行是否在进行 ...