洛谷P2429 制杖题 [2017年6月计划 数论10]

Posted 嘒彼小星

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷P2429 制杖题 [2017年6月计划 数论10]相关的知识,希望对你有一定的参考价值。

P2429 制杖题

题目描述

求不大于 m 的、 质因数集与给定质数集有交集的自然数之和。

输入输出格式

输入格式:

第一行二个整数 n,m。

第二行 n 个整数,表示质数集内的元素 p[i]。

输出格式:

一个整数,表示答案,对 376544743 取模。

输入输出样例

输入样例#1:
2 15
3 5
输出样例#1:
60

说明

样例解释:所有符合条件的数为 3,5,6,9,10,12,15 其和为 60。

··· 测试点编号 规模

1 2 3 n*m<=10^7
4 5 n<=2,m<=10^9
6 7 n<=20,m<=10^8
8 9 10 n<=20,m<=10^9
···


 

前三个点:n * m <= 1e7

不难想到暴力求解

 

后七个点:n <= 20,m <= 1e9

容斥+等差数列求和

利用二进制枚举各个数的乘积,利用等差数列求和,容斥原理排除多算的即可

 

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring> 
#include <algorithm>
#include <vector>
#include <queue>
inline void read(long long &x){x = 0;char ch = getchar();char c = ch;while(ch > 9 || ch < 0)c = ch, ch = getchar();while(ch >= 0 && ch <= 9)x = x * 10 + ch - 0, ch = getchar();}
inline int max(int a, int b){return a > b ? a : b;}
inline int min(int a, int b){return a < b ? a : b;}
inline void swap(int &a, int &b){int tmp = a;a = b;b = tmp;}

const int INF = 0x3f3f3f3f;
const int MAXN = 2000 + 5;
const int MOD =  376544743;

long long n,m;
long long p[MAXN];
long long ans;

int main()
{
    read(n);read(m);
    for (register long long i = 1 ; i <= n ; ++ i)
        read(p[i]);
    if(n * m <= 100000000)
    {
        for(int i = 1;i <= m;i ++)
        {
            for(int j = 1;j <= n;j ++)
            {
                if(!(i % p[j]))
                {
                    ans += i;
                    ans %= MOD;
                    break;
                }
            }
        }
        printf("%lld", ans % MOD);
        return 0;
    }

    int S = (1 << n);
    register long long num,cnt,x;
    register long long niyuan = (MOD + 1)/ 2;
    
    for (register long long i = 1 ; i < S ; ++ i)
    {
        register long long num = 1,cnt = 0,x = 0;
        for (register long long j = 1, k = i ; k ; ++j, k >>= 1)
            if (k & 1)num *= p[j],x ++;
        cnt = m / num;
        if (x)
        {
            if (x & 1)
                ans += (((num * (1 + cnt))%MOD * cnt)%MOD * niyuan) % MOD;
            else
                ans -= (((num * (1 + cnt))%MOD * cnt)%MOD * niyuan) % MOD;
            ans = ans % MOD;
        }
    }
    printf("%lld", ans % MOD);
    return 0;
}

 

以上是关于洛谷P2429 制杖题 [2017年6月计划 数论10]的主要内容,如果未能解决你的问题,请参考以下文章

洛谷P1062 数列 [2017年6月计划 数论03]

洛谷P2667 超级质数 [2017年6月计划 数论05]

洛谷P1978 集合 [2017年6月计划 数论08]

洛谷P1890 gcd区间 [2017年6月计划 数论09]

洛谷P1147 连续自然数和 [2017年6月计划 数论01]

洛谷P2723 丑数 Humble Numbers [2017年 6月计划 数论07]