Codeforces 900D Unusual Sequences 容斥原理

题目链接:900D  Unusual Sequences

题意:

  给出两个数N,M。让你求数列(和为M,gcd为N)的个数。

题解:

  首先,比较容易发现的是M%N如果不为零,那么一定不能构成这样的序列。那么可以设 k = M/N,则可以想象为用k个1来构成序列的个数,运用隔板原理可以求出k个1可以构成的序列总数为2^(k-1),但是这里面其实有不构成条件的(gcd>N)比方说6个相同的数(2,2,2)构成这样gcd就是2×N而不是N了。所以要减去这些数的情况,这样减的话发现不能用递归来做,要先记忆化。记忆化因为这里面最大的数是1e9不能用数组储存,要用map离散。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int MAX_N=1e5+5;
 4 const int MOD = 1e9+7;
 5 map<long long , long long > mp;
 6 long long quick_pow(int x)
 7 {
 8     x -= 1;
 9     long long base = 2;
10     long long ans = 1;
11     while(x)
12     {
13         if(x&1) ans = (ans * base)%MOD;
14         x >>= 1;
15         base = (base*base)%MOD;
16     }
17     return ans;
18 }
19 long long solve(int x)
20 {
21     if(mp.count(x)) return mp[x];
22     long long ans = quick_pow(x)-1;
23     for(int i=2;i*i<=x;i++)
24     {
25         if(x%i == 0)
26         {
27             ans = (ans - solve(i) + MOD)%MOD;
28             if(x/i != i)
29             {
30                 ans = (ans - solve(x/i) + MOD)%MOD;
31             }
32         }
33     }
34     mp.insert(make_pair(x,ans));
35     return ans;
36 }
37 int main()
38 {
39     long long N,M,T;
40     mp.insert(make_pair(1,1));
41     while(cin>>N>>M)
42     {
43         if(M%N != 0)
44         {
45             printf("0\n");
46         }
47         else
48         {
49             printf("%lld\n",solve(M/N));
50         }
51     }
52     return 0;
53 }

原文地址:https://www.cnblogs.com/doggod/p/8334879.html

时间: 2024-10-21 16:33:37

Codeforces 900D Unusual Sequences 容斥原理的相关文章

CF 900D Unusual Sequences

题目链接 \(Description\) 给定\(x,y\),求有多少个数列满足\(gcd(a_i)=x且\sum a_i=y\).答案对\(10^9+7\)取模. \(1≤x,y≤10^9\) \(Solution\) \(y\)如果不是\(x\)的倍数,答案为\(0\) 然后呢 令\(y/=x\),问题就变成了求有多少个数列满足\(gcd(a_i)=1且\sum ai=y'\) 如果没有\(gcd\)为\(1\)的限制? 隔板法可得\(ans=\sum_{i=0}^{y-1}C_{y-1}^

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 *

CodeForces 373B Making Sequences is Fun

Making Sequences is Fun Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit Status Practice CodeForces 373B Description We'll define S(n) for positive integer n as follows: the number of the n's digits in the decimal

[Codeforces#264B] Good Sequences

Codeforces题号:#264B 出处: Codeforces 主要算法:DP 难度:4.8 思路分析: 这题DP太难了…… 最终的解法是,令f[i]表示存在因子i的一个数作为子序列结尾的子序列的最大长度.(定义都好难懂啊……) 现在想一想怎么转移……首先先预处理出对于每一个数a[i]的所有因数.既然相邻的两个数不能是互质的,我们只需要判断相邻两个数的最大公约数是否大于1就好了. 那么如何判断能否连起来呢?依次枚举a[i],并枚举刚才处理好的a[i]的因数.为什么好枚举因数, 因为所有因数如

CodeForces 264B Good Sequences dp

题目链接:点击打开链接 题意: 给定n个数, 构造一个序列(只能选给出的n个数,但数字可重复用) 使得序列严格递增且相邻的两个数字不互质 思路: 因为是严格递增,所以给输入的n个数排个序,相当于选n个数中的子序列了. 把每个数都分解质因数,然后用质因数转移方程即可. import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.PrintWriter; import java.math.BigInt

Codeforces Jzzhu and Sequences(循环节)

# include <stdio.h> int f[10]; int main() { int x,y,n,j; while(~scanf("%d%d%d",&x,&y,&n)) { f[1]=x; f[2]=y; for(j=3;j<=6;j++) { f[j]=f[j-1]-f[j-2]; } n%=6; if(n==0) n=6; if(f[n]>=0) printf("%d\n",f[n]%1000000007

Unusual Sequences

题意: 求解合为 y 的总体 gcd 为 x 的正整数非空序列个数. 解法: 特判一下后,原问题等价于合为 s = y/x 的整体gcd为1的正整数序列个数. 1.$ans = \sum_{\sum{x_i} = s}{ [(x_1,...,x_n) = 1] } = \sum_{d|s}{\mu(s/d) \sum{[x_1+x_2+...+x_n = d]}} = \sum_{d|s}{\mu(s/d) 2^{d-1}}$ 2.记$f(m) = \sum_{\sum{x_i} = m}{ [

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)

【CF900D】Unusual Sequences

题目 智力下降严重 显然要反演了呀 首先必须满足\(x|y\),否则答案是\(0\) 我们枚举这个数列的\(gcd\)是\(d\)或者\(d\)的倍数 于是答案就是 \[\sum_{x|d}[d|y]\mu(\frac{x}{d})g(\frac{y}{d})\] \(g(d)\)表示和为\(d\)的正整数数列的数量,显然就是插一下板,于是\(g(d)=\sum_{i=1}^d\binom{d-1}{i-1}=2^{d-1}\) 代码 #include<bits/stdc++.h> #defi