zoukankan      html  css  js  c++  java
  • 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
    ");
    46         }
    47         else
    48         {
    49             printf("%lld
    ",solve(M/N));
    50         }
    51     }
    52     return 0;
    53 }
  • 相关阅读:
    spring学习(一)IOC&AOP
    MongoDB 写入数据的安全性
    MongoDB MapReduce
    MongoDB 原子操作
    MongoDB 文档间的关系
    MongoDB Java
    MongoDB 持久化
    MongoDB 聚合函数 aggregate
    MongoDB 索引
    MongoDB 文档操作
  • 原文地址:https://www.cnblogs.com/doggod/p/8334879.html
Copyright © 2011-2022 走看看