传送门


数字最小公倍数为\(L\)的充分条件是所有数都是\(L\)的约数,而\(10^8\)内最多约数的数的约数也只有\(768\)个。所以我们先暴力找到所有满足是\(L\)的约数、\(G\)的倍数的数。

接下来注意到题目的\(\gcd\)和\(lcm\)的限制等价于对于每一个质数限制所有数在该质数指数上的\(\min\)和\(\max\)。在\(10^8\)内质数数量最多的数只有\(8\)个质数,所以我们对于第一步中求出的数用一个二进制数记录下它每一个质数的指数是否等于限制的\(\min\)和\(\max\)。那么问题就变成了选择子集满足按位或为全集的方案数。

对于这个问题考虑容斥,即强制某些位置在或的过程当中不被取到,那么答案就是\(\sum\limits_{S \subseteq U} (-1)^{|U-S|} 2^{\sum\limits_{j \subseteq S}1}\)。

后面的\(\sum\limits_{j \subseteq S}1\)可以通过高维前缀和求得。

最后我们需要求出所有数字的答案,那么我们只需要先算出所有数都可选择的答案,然后把当前数从高维前缀和中删掉计算其他数可以选择的答案相减即可。

复杂度\(O(2^{2\omega(n)} d(n)+Q)\),其中\(\omega(n),d(n)\)分别是质数个数、约数个数。

#include<bits/stdc++.h>
using namespace std;const int MOD = 1e9 + 7; map < int , int > ans;
int prm , Pow2[800] , cnt[1 << 16] , N , G , L , Q; vector < int > num , val;int poww(long long a , int b){int times = 1;while(b){if(b & 1) times = times * a % MOD;a = a * a % MOD; b >>= 1;}return times;
}void calc(int id , int x){int p = G , q = L , cnt1 = 0 , cnt2 = 0;while(p % x == 0){++cnt1; p /= x;}while(q % x == 0){++cnt2; q /= x;}for(int j = 0 ; j < num.size() ; ++j){int cur = num[j] , cnt = 0;while(cur % x == 0){++cnt; cur /= x;}if(cnt == cnt1) val[j] |= 1 << id;if(cnt == cnt2) val[j] |= 1 << (id + prm);}
}int main(){cin >> N >> G >> L >> Q;if(L % G){for(int i = 1 ; i <= Q ; ++i) cout << "0\n"; return 0;}for(int i = 1 ; i <= N && i * i <= L ; ++i)if(L % i == 0){if(i % G == 0) num.push_back(i);if(L / i <= N && L / i != i && (L / i) % G == 0) num.push_back(L / i);}int tp = L; val.resize(num.size());for(int i = 2 ; i * i <= tp ; ++i) if(tp % i == 0){++prm; while(tp % i == 0) tp /= i;}if(tp - 1) ++prm; tp = L; int tc = 0;for(int i = 2 ; i * i <= tp ; ++i)if(tp % i == 0){calc(tc++ , i); while(tp % i == 0) tp /= i;}if(tp - 1) calc(tc++ , tp);for(int i = 0 ; i < val.size() ; ++i) ++cnt[val[i]];for(int i = 0 ; i < 2 * prm ; ++i)for(int j = 0 ; j < 1 << (2 * prm) ; ++j)if(j >> i & 1) cnt[j] += cnt[j ^ (1 << i)];Pow2[0] = 1; for(int i = 1 ; i <= num.size() ; ++i) Pow2[i] = (Pow2[i - 1] << 1) % MOD;int all = 0;for(int j = 0 ; j < 1 << (2 * prm) ; ++j)all = (all + (__builtin_popcount(j) & 1 ? MOD - 1ll : 1ll) * Pow2[cnt[j]]) % MOD;for(int i = 0 ; i < num.size() ; ++i){int sum = 0;for(int j = 0 ; j < 1 << (2 * prm) ; ++j) if((val[i] & j) == val[i]) --cnt[j];for(int j = 0 ; j < 1 << (2 * prm) ; ++j)sum = (sum + (__builtin_popcount(j) & 1 ? MOD - 1ll : 1ll) * Pow2[cnt[j]]) % MOD;ans[num[i]] = (all + MOD - sum) % MOD;for(int j = 0 ; j < 1 << (2 * prm) ; ++j) if((val[i] & j) == val[i]) ++cnt[j];}while(Q--){int x; cin >> x; cout << ans[x] << endl;}return 0;
}

转载于:https://www.cnblogs.com/Itst/p/11558147.html

LOJ2257 SNOI2017 遗失的答案 容斥、高维前缀和相关推荐

  1. Codeforces.449D.Jzzhu and Numbers(容斥 高维前缀和)

    题目链接 \(Description\) 给定\(n\)个正整数\(a_i\).求有多少个子序列\(a_{i_1},a_{i_2},...,a_{i_k}\),满足\(a_{i_1},a_{i_2}, ...

  2. LuoguP5366 [SNOI2017]遗失的答案

    LuoguP5366 [SNOI2017]遗失的答案 题目描述 Solution 可以先简化问题,特判LLL不是GGG倍数的情况. 然后令n=⌊nG⌋n=\lfloor \frac{n}{G} \rf ...

  3. [SNOI2017]遗失的答案

    遗失的答案 题解 其实这题挺水的. 显然,当 G ∤ L G\not | \,\,\,L G​∣L时是无解的.我们可以先将小于 n n n的不是 G G G倍数的值全部舍去,只用管为 G G G倍 ...

  4. [SNOI2017]遗失的答案 (FWT)

    description 小皮球在计算出答案之后,买了一堆皮肤,他心里很开心,但是一不小心,就忘记自己买了哪些皮肤了.= =||| 万幸的是,他还记得他把所有皮肤按照 1∼N 来编号,他买来的那些皮肤的 ...

  5. P4318 完全平方数 [二分答案+容斥+莫比乌斯函数]

    完 全 平 方 数 完全平方数 完全平方数 D e s c r i p t i o n \mathcal{Description} Description 小 X 自幼就很喜欢数.但奇怪的是,他十分讨 ...

  6. 【BZOJ2440】完全平方数,莫比乌斯反演+二分答案+容斥思想

    Time:2016.05.29 Author:xiaoyimi 转载注明出处谢谢 传送门 思路: 这是一个和μ函数有很大关系的题目 x以内的无平方因子数=无需是任何质数的倍数的数的数量(即x)-是至少 ...

  7. P4318-莫比乌斯函数+容斥

    前言: 这题告诉我们莫比乌斯函数是平方数容斥的容斥系数. 题目大意: T T T组询问,问你第 k k k个不含平方因子的数. 题目思路:二分答案+容斥 先二分答案 m i d mid mid,问题转 ...

  8. Codeforces Round #257 (Div. 1) D. Jzzhu and Numbers 高维前缀和 + 容斥

    传送门 文章目录 题意: 思路: 题意: 思路: 完全想不到容斥啊,看了半天也没看懂渍渍渍. 定义f[i]f[i]f[i]表示iii的超集个数,那么选择的方案就是2f[i]−12^{f[i]}-12f ...

  9. P4318,bzoj2440-完全平方数【二分答案,莫比乌斯函数,容斥】

    正题 题目链接: https://www.luogu.org/problem/P4318 https://www.lydsy.com/JudgeOnline/problem.php?id=2440 题 ...

  10. P5643-[PKUWC2018]随机游走【min-max容斥,dp】

    正题 题目链接:https://www.luogu.com.cn/problem/P5643 题目大意 给出nnn个点的一棵树,一个人从点xxx开始随机游走,然后QQQ次询问给出一个点集SSS,求期望 ...

最新文章

  1. 在vue中使用vuex,修改state的值示例
  2. 解决ubuntu软件安装依赖关系
  3. go.sum中特殊hash如何计算
  4. python阻塞和非阻塞_Python基础必备知识:同步异步阻塞非阻塞
  5. 前端数据可视化可绘制地图等插件:Highcharts、Echarts和D3
  6. 既可输入又可选择的组件
  7. GDCM:Dicom文件Empty Mask的测试程序
  8. sql执行有时候快有时候慢_如何让你的 SQL 执行的飞起?
  9. 最新的Windows phone Developer tools RTW 发布了
  10. apache gobblin mysql_incubator-gobblin-master
  11. 流媒体服务器性能测试
  12. (18)ADS1675高速模式采样率异常解决(学无止境)
  13. (116)FPGA面试题-FIFO相关参数与信号,为什么要用格雷码
  14. Python遍历破解FTP密码,并上传webshell
  15. python植物大战僵尸代码
  16. (TeamTalk服务端源码分析一)TeamTalk服务端部署
  17. WebRtc与P2P
  18. Windows server 2019 安装VPN
  19. 利用spring的jdbcTemplate处理blob、clob
  20. Gavin Wood的故事:神级黄皮书、出走以太坊、乱世成名与三代区块链

热门文章

  1. resnet和densenet系列模型结构图可视化
  2. html tooltip 换行,echarts在tooltip中换行操作
  3. mysql 程序编码_MySql编码
  4. 云原生技术学习路线图 初阶+中阶+高阶
  5. HyperLedger Composer 如何安装、小白入门教程
  6. 浅析引用类型和基本类型的内存比较
  7. 结尾匹配_2.nginx的server_name匹配顺序
  8. 19春北理工计算机应用基础,19春北理工《计算机应用基础》在线作业(02)【标准答案】.doc...
  9. 微信支付jsapi并写入数据库--回调函数(notify.php)的使用
  10. 利用后中遍历结果,重构二叉树