栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C. Strange Function「思维 + 数论」

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C. Strange Function「思维 + 数论」

C. Strange Function 题目描述:

定义f(i)为最小的不能被 i 整除的正整数

求 ∑ i = 1 n f ( i ) sum_{i=1}^{n}f(i) ∑i=1n​f(i),1<=n<=1e16

思路:

打表发现根本找不到规律

暴力算肯定不行,毕竟n巨大

这个时候就该想想在n这么大的情况下不能暴力,也没有规律该怎么办

对于f(i) = x,我们分析一下会发现,因为 x 是最小的不能被 i 整除的最小正数,就说明其实 i 能整除 1 到 i - 1中的任何一个,也就是能整除lcm(1, 2, ……, x-1),但是绝对不能整除 x ,也就是说不能整除lcm(1, 2, ……, x),可以发现其实 x 的值不会很大,不到100,那我们就需要一个可以快速的统计出 n 个数中对于每个 x 满足 f(i) = x 的 i 的数量的方法就可以解决问题,根据上面写的两个lcm可以做一个容斥,f(i) = x的个数其实就等于 n u m = n / ( l c m ( 1 , 2 , 3 … … x − 1 ) ) − n / ( l c m ( 1 , 2 , 3 … … , x ) ) num = n / (lcm(1,2,3……x-1)) - n/(lcm(1,2,3……,x)) num=n/(lcm(1,2,3……x−1))−n/(lcm(1,2,3……,x)),而这个x产生的贡献就是x * num,而当lcm大于n的时候就不会再产生ans的贡献了就可以直接输出

总结:

当数据范围巨大的时候,考虑能否进行数论分块,分别计算每个块的答案

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//#include
using namespace std;

//#pragma GCC optimize("Ofast")
//#pragma GCC target("fma,sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2,tune=native")
//#pragma GCC optimize("unroll-loops")

#define eps 1e-8
#define endl 'n'
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3f
#define NMAX 1000 + 50
#define ls p<<1
#define rs p<<1|1
#define mod 1000000007
#define lowbit(x) (x & (-x))
#define sz(s) (int)(s).size()
#define sd(n) scanf("%d",&n)
#define sdd(n,m) scanf("%d %d",&n,&m)
#define sl(n) scanf("%lld",&n)
#define sll(n,m) scanf("%lld %lld",&n,&m)
#define pd(n) printf("%dn", (n))
#define pdd(n,m) printf("%d %dn",n, m)
#define sddd(n,m,z) scanf("%d %d %d",&n,&m,&z)
#define slll(n,m,z) scanf("%lld %lld %lld",&n,&m,&z)
#define io ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define mem(a,b) memset((a),(b),sizeof(a))
#define m_p(a,b) make_pair(a, b)
typedef  long long ll;
typedef pair  pii;
typedef unsigned long long ull;
//不开longlong见祖宗!
inline int IntRead(){char ch = getchar();int s = 0, w = 1;while(ch < '0' || ch > '9'){if(ch == '-') w = -1;ch = getchar();}while(ch >= '0' && ch <= '9'){s = s * 10 + ch - '0';ch = getchar();}return s * w;}

//不改范围见祖宗!!!
#define MAX 1000000 + 50
ll n, m, k;
int x, y, z;
ll a, b, c;
string s, t;

ll gcd(ll a, ll b){
    if(b) return gcd(b, a % b);
    else return a;
}
ll lcm(ll a, ll b){
    return a / gcd(a, b) * b;
}

void work(){
    cin>>n;
    ll p = 1;
    ll ans = 0;
    for(ll i = 2;; ++i){
        ans = ans + (i * (n / p - n / lcm(p, i)) % mod) % mod;
        ans %= mod;
        p = lcm(p, i);
        if(p > n)break;
    }
    cout<>tt;
    for(int _t = 1; _t <= tt; ++_t){
//        printf("Case #%d: ", _t);
        work();
    }
    return 0;
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/510640.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号