AtCoder-abc254_d Together Square

Together Square#

唯一分解定理 + 递推

如果从 n1 递推到 n 的话,只要考虑任意的组合 (i,n) i<n 的所有个数的 2 倍,再加上一个 (n,n) 就可以了

接下来就考虑能不能快速求出 (i,n) 满足条件的个数

如果一个数是平方数,则质因数分解出来的频率均为偶数,我们可以根据这个要求要计算

考虑质因数分解,如果 n 分解出来的质因数的频率是偶数次,则无影响,如果是奇数次,则会要求 i 的质因数分解中,该质数出现的频率为奇数

我们先算出所有 i 必须带有的质数的乘积,然后剩下的就是求平方数的次数了,显然有:要求小于等于 x 的平方数的个数,答案为 x

因为 i 的范围是 1i<n,且 i=xk2,x 为 i 必须带有的质数乘积,k2 表示平方数,则其数量的计算就为 n1x

质因数分解的话,直接用欧拉筛的方式预处理所有合数的其中一个因数,然后不断往下除就是了

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
int num[maxn], pre[maxn];
ll dp[maxn];

void init(int n)
{
    pre[1] = 1;
    for(int i=2; i<=n; i++)
    {
        if(pre[i]) continue;
        for(int j=i; j<=n; j+=i)
            pre[j] = i;
    }
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n;
    cin >> n;
    init(n);
    for(int i=1; i<=n; i++)
    {
        ll temp = 0;
        if(pre[i] != i)
        {
            ll x = i, ans = 1;
            while(pre[x] != x)
            {
                ll now = pre[x], way = 0;
                while(pre[x] == now)
                {
                    x /= pre[x];
                    way++;
                }
                if(way & 1)
                    ans *= now;
            }
            ans *= pre[x];
            temp = sqrt((i - 1) / ans);
        }
        dp[i] = dp[i-1] + temp * 2 + 1;
    }
    cout << dp[n] << endl;

    return 0;
}
posted @   dgsvygd  阅读(534)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示
主题色彩