zoukankan      html  css  js  c++  java
  • Codeforces 900D Unusual Sequences:记忆化搜索

    题目链接:http://codeforces.com/problemset/problem/900/D

    题意:

      给定x,y,问你有多少个数列a满足gcd(a[i]) = x 且 ∑(a[i]) = y。

    题解:

      由于gcd(a[i]) = x,所以y一定是x的倍数,否则无解。

      那么原题就等价于:问你有多少个数列a满足gcd(a[i]) = 1 且 ∑(a[i]) = y/x。

     

      设f(k)为gcd(a[i]) = 1 且 ∑(a[i]) = k时的答案。

      只满足条件∑(a[i]) = k的数列共有2^(k-1)种(隔板法)

      然后要从中去掉gcd不为1的数列。

      每个和为k且gcd不为1的数列a1,对应着一个和为k的因数且gcd为1的数列a2。

      因为a1可以由a2整体放大而来。

      那么也就是f(k) = 2^(k-1) - ∑ f(p),其中p为k的因数(p != k)。

      搜索 + map记忆化即可。

     

      由于需要用到的f(k),k均为y/x的因数,最多sqrt(y/x)个。

      加上map的log复杂度,所以总复杂度为O(sqrt(n)*log(n))。

    AC Code:

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 #include <map>
     5 #define MOD 1000000007
     6 
     7 using namespace std;
     8 
     9 int x,y;
    10 map<int,int> mp;
    11 
    12 long long quick_pow(long long n,long long k)
    13 {
    14     long long ans=1;
    15     while(k>0)
    16     {
    17         if(k&1) ans=(ans*n)%MOD;
    18         n=n*n%MOD;
    19         k>>=1;
    20     }
    21     return ans;
    22 }
    23 
    24 long long dfs(int i)
    25 {
    26     if(i==1) return 1;
    27     if(mp.count(i)) return mp[i];
    28     long long ans=quick_pow(2,i-1);
    29     for(int j=2;j*j<=i;j++)
    30     {
    31         if(i%j==0)
    32         {
    33             ans=((ans-dfs(j))%MOD+MOD)%MOD;
    34             if(i/j!=j) ans=((ans-dfs(i/j))%MOD+MOD)%MOD;
    35         }
    36     }
    37     ans=((ans-1)%MOD+MOD)%MOD;
    38     return mp[i]=ans;
    39 }
    40 
    41 int main()
    42 {
    43     cin>>x>>y;
    44     cout<<(y%x==0 ? dfs(y/x) : 0)<<endl;
    45 }
  • 相关阅读:
    android模拟器上网设置
    20150916自动化测试之Appinum For Android(环境搭建之下载更新安装AndroidSDK包)
    测试部门目标
    grade 错误
    质量保证
    emma覆盖率
    python学习(二)--数据类型
    python学习(一)--python解释器
    fidder从基础到熟练
    这几天帮一个朋友解决了一点小问题(RF的有些小问题及解决过程)
  • 原文地址:https://www.cnblogs.com/Leohh/p/8464069.html
Copyright © 2011-2022 走看看