codeforce 954 div3 G2题

思路:

质因子分解可以顺着分解,也可以逆着分解

即找到每一个数字的倍数,再找到每一个数字的因数

cpp 复制代码
const int N = 5e5+10;
vector<int> ff[N];
vector<int> f[N];
vector<int> g[N];

void solve(){
    int n;
    cin>>n;
    vector<int> nums(n+1,0);
    ll ans = 0;
    for(int i = 1;i<=n;i++){
        cin>>nums[i];
    }
    for(int i = 1;i<=n;i++){
        int w = gcd(i,nums[i]);
        int x = i/w,y = nums[i]/w;
        //cout<<x<<" "<<y<<" eeeeee"<<endl;
        if(nums[i]%i == 0)  ans--;
        f[x].emplace_back(y);
        g[y].emplace_back(x);
    }
    vector<int>cnt(n+1,0);
    for(int i = 1;i<=n;i++){
        int m = f[i].size();
        if(m == 0)  continue;
        sort(f[i].begin(),f[i].end());
        for(int j = i;j<=n;j+=i){
            for(auto x : g[j]){
                cnt[x]++;
            }
        }
        for(int j = 0;j<m;j++){
            int k = 1;
            while(j<m-1 && f[i][j] == f[i][j+1]){
                j++;
                k++;
            }
            int y = f[i][j];
            ll sum = 0;
            for(auto son : ff[y]){
                sum += cnt[son];
            }
            sum *= k;
            ans += sum;
        }


        for(int j = i;j<=n;j+=i){
            for(auto x : g[j]){
                cnt[x]--;
            }
        }
    }
    for(int i = 1;i<=n;i++){
        f[i].clear();
        g[i].clear();
    }
    cout<<ans/2<<endl;
}
相关推荐
今天背单词了吗98019 分钟前
算法学习笔记:11.冒泡排序——从原理到实战,涵盖 LeetCode 与考研 408 例题
java·学习·算法·排序算法·冒泡排序
汤姆爱耗儿药31 分钟前
专为磁盘存储设计的数据结构——B树
数据结构·b树
看到我,请让我去学习1 小时前
OpenCV编程- (图像基础处理:噪声、滤波、直方图与边缘检测)
c语言·c++·人工智能·opencv·计算机视觉
倔强的小石头_3 小时前
【C语言指南】函数指针深度解析
java·c语言·算法
Yasin Chen4 小时前
C# Dictionary源码分析
算法·unity·哈希算法
_Coin_-5 小时前
算法训练营DAY27 第八章 贪心算法 part01
算法·贪心算法
许小燚8 小时前
线性表——双向链表
数据结构·链表
董董灿是个攻城狮9 小时前
5分钟搞懂什么是窗口注意力?
算法
Dann Hiroaki9 小时前
笔记分享: 哈尔滨工业大学CS31002编译原理——02. 语法分析
笔记·算法
xiaolang_8616_wjl10 小时前
c++文字游戏_闯关打怪2.0(开源)
开发语言·c++·开源