cf900D. Unusual Sequences(容斥 莫比乌斯反演)

题意

题目链接

Sol

首先若y % x不为0则答案为0

否则,问题可以转化为,有多少个数列满足和为y/x,且整个序列的gcd=1

考虑容斥,设\(g[i]\)表示满足和为\(i\)的序列的方案数,显然\(g[i] = 2^{i-1}\)(插板后每空位放不放)

同时还可以枚举一下gcd,设\(f[i]\)表示满足和为\(i\)且所有数的gcd为1的方案,\(g[i] = \sum_{d | i} f[\frac{n}{d}]\)

反演一下,\(f[i] = \sum_{d | i} \mu(d) g(\frac{i}{d})\)

mu函数可以暴力枚举质因子得到

复杂度\(O(2^{Mx} * Mx + \sqrt{N}\) ,\(Mx\)最大为10

#include<bits/stdc++.h>
#define Pair pair<int, int>
#define MP(x, y) make_pair(x, y)
#define fi first
#define se second
#define int long long
#define LL long long
#define Fin(x) {freopen(#x".in","r",stdin);}
#define Fout(x) {freopen(#x".out","w",stdout);}
//#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1<<22, stdin), p1 == p2) ? EOF : *p1++)
//char buf[(1 << 22)], *p1 = buf, *p2 = buf;
using namespace std;
const int MAXN = 1e6 + 10, mod = 1e9 + 7, INF = 1e9 + 10;
const double eps = 1e-9;
template <typename A, typename B> inline bool chmin(A &a, B b){if(a > b) {a = b; return 1;} return 0;}
template <typename A, typename B> inline bool chmax(A &a, B b){if(a < b) {a = b; return 1;} return 0;}
template <typename A, typename B> inline LL add(A x, B y) {if(x + y < 0) return x + y + mod; return x + y >= mod ? x + y - mod : x + y;}
template <typename A, typename B> inline void add2(A &x, B y) {if(x + y < 0) x = x + y + mod; else x = (x + y >= mod ? x + y - mod : x + y);}
template <typename A, typename B> inline LL mul(A x, B y) {return 1ll * x * y % mod;}
template <typename A, typename B> inline void mul2(A &x, B y) {x = (1ll * x * y % mod + mod) % mod;}
template <typename A> inline void debug(A a){cout << a << '\n';}
template <typename A> inline LL sqr(A x){return 1ll * x * x;}
inline int read() {
    char c = getchar(); int x = 0, f = 1;
    while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * f;
}
int x = read(), y = read();
map<int, int> mu;
int g(int a, int p) {
    int base = 1;
    while(p) {
        if(p & 1) base = mul(base, a);
        p >>= 1; a = mul(a, a);
    }
    return base;
}
signed main() {
    if(y % x != 0) return puts("0"), 0;
    vector<int> d; y /= x; int p = y;
    for(int i = 2; i * i <= y; i++)
        if(!(y % i)) {
            d.push_back(i);
            while(!(y % i)) y /= i;
        }
    if(y != 1) d.push_back(y);
    y = p;
    for(int sta = 0; sta < (1 << d.size()); sta++) {
        int v = 1, t = 1;
        for(int i = 0; i < d.size(); i++) if(sta & (1 << i)) t *= -1, v *= d[i];
        mu[v] = t;
    }
    int ans = 0;
    for(auto &x: mu) {
        int d = x.fi, m = x.se;
        add2(ans, mul(m + mod, g(2, y / d - 1)));
    }
    cout << ans;
    return 0;
}

原文地址:https://www.cnblogs.com/zwfymqz/p/10327298.html

时间: 2024-11-05 20:41:32

cf900D. Unusual Sequences(容斥 莫比乌斯反演)的相关文章

【二分+容斥+莫比乌斯反演】BZOJ2440 完全平方数

Description 求第k个没有完全平方因子的数,k<=1e9. Solution 这其实就是要求第k个µ[i](莫比乌斯函数)不为0的数. 然而k太大数组开不下来是吧,于是这么处理. 二分答案x,问题转化为求[1,x]间有多少个没有完全平方因子的数. 容斥,加上全部,减去一个质数的平方的倍数个数,加上两个质数乘积的平方的倍数个数... 然后发现,每个数的系数就是µ 这也说明了莫比乌斯的原理就是容斥,µ函数就是容斥系数 具体来说,对于每一个i<=sqrt(x),对于ans的贡献就是µ[i]

bzoj 4671 异或图 —— 容斥+斯特林反演+线性基

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4671 首先,考虑容斥,就是设 \( t[i] \) 表示至少有 \( i \) 个连通块的方案数: 我们希望得到恰好有一个连通块的方案数,但这里不能直接 \( + t[1] - t[2] + t[3] - t[4] ... \),因为每个"恰好 \( i \) 个连通块"的情况并不是在各种 \( t[j] ( j<=i ) \) 中只被算了一次,而是因为标号,被算了 \(

【bzoj4671】异或图(容斥+斯特林反演+线性基)

传送门 题意: 给出\(s,s\leq 60\)张图,每张图都有\(n,n\leq 10\)个点. 现在问有多少个图的子集,满足这些图的边"异或"起来后,这张图为连通图. 思路: 直接考虑判断图的连通不好判断,所以考虑枚举连通块来进行容斥. 定义\(f_i\)表示有\(i\)个连通块的答案,发现连通块这个东西也不好处理,我们只能处理出有多少个连通块,但无法确定每个连通块内部的连通关系. 定义\(g_i\)为至少有\(i\)个连通块的方案数,那么就有关系式:\(\displaystyle

D. Unusual Sequences(容斥)

D. Unusual Sequences 隔板法 + 容斥原理 1 //容斥(莫比乌斯反演) 2 #include <bits/stdc++.h> 3 using namespace std; 4 #define LL long long 5 const int mod = 1e9+7; 6 LL quickpow(LL a, LL b, LL mod){ 7 LL temp = a % mod, res = 1; 8 while(b){ 9 if(b & 1) res = res *

HDU 1695 GCD(容斥 or 莫比乌斯反演)

这题可以用容斥做,然而效率并不高.. 于是学了下莫比乌斯反演(资料百度找) 求出mo数组后 设f(x)为gcd为x的种数 F(x)为gcd为x倍数的种数 那么显然F(x) = (b / x) * (d / x) 莫比乌斯反演之后,得到f(x) = sum(mo[i] * F(i)). 然后还要容斥减去对称重复的.对称重复的情况为min(b, d)小的中,求一遍除2,(因为存在x = y的情况只有(1,1)一种) 最后还要注意特判下k == 0的情况 代码: #include <cstdio>

Coprime (单色三角形+莫比乌斯反演(数论容斥))

这道题,先说一下单色三角形吧,推荐一篇noip的论文<国家集训队2003论文集许智磊> 链接:https://wenku.baidu.com/view/e87725c52cc58bd63186bd1b.html?from=search 单色三角形指的是n个顶点,有n(n-1)条边,很明显是每个点两两相连,那么这样所形成的所有三角形的边假如有两种颜色:红和黑.那么问一共有多少三角形的三边是一种颜色的个数. ,建议看一下那个论文,因为我只能直接给出你结论.  下面的数学符号:{...}为概率论中表

HDU 5072 Coprime (莫比乌斯反演+容斥+同色三角形)

Coprime Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 1469    Accepted Submission(s): 579 Problem Description There are n people standing in a line. Each of them has a unique id number. Now

BZOJ 2440 完全平方数 (容斥+莫比乌斯反演+二分)

2440: [中山市选2011]完全平方数 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 1673  Solved: 799 [Submit][Status][Discuss] Description 小 X 自幼就很喜欢数.但奇怪的是,他十分讨厌完全平方数.他觉得这些 数看起来很令人难受.由此,他也讨厌所有是完全平方数的正整数倍的数.然而 这丝毫不影响他对其他数的热爱. 这天是小X的生日,小 W 想送一个数给他作为生日礼物.当然他不能送一 个

JZYZOJ1518 [haoi2011]b 莫比乌斯反演 分块 容斥

http://172.20.6.3/Problem_Show.asp?id=1518最开始只想到了n^2的写法,肯定要超时的,所以要对求gcd的过程进行优化.首先是前缀和容斥,很好理解.第二个优化大致如下:u为莫比乌斯函数,t为gcd(x,y)为i的倍数的数的个数:满足gcd(x,y)=1的数字对的数量=sigma(1<=i<=min(x,y))u[i]*t[i];t[i]=(x/i)*(y-i);由小数向下取整可知有连续的i满足x/i为定值,y/i也是定值,所以可以分块计算,用u[i]的前缀