zoukankan      html  css  js  c++  java
  • ACM学习历程—广东工业大学2016校赛决赛-网络赛F 我是好人4(数论)

    题目链接:http://gdutcode.sinaapp.com/problem.php?cid=1031&pid=5

    这个题目一看就是一道数论题,应该考虑使用容斥原理,这里对lcm进行容斥。

    不过直接上去是T,考虑到序列中同时存在iki的话,其实只需要考虑i,所以先对序列中为倍数的对进行处理。

    这里的容斥用了hqw的写法。

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <cstring>
    #include <algorithm>
    #include <set>
    #include <map>
    #include <queue>
    #include <vector>
    #include <string>
    #define LL long long
    
    using namespace std;
    
    const LL maxN = 1e9;
    int n;
    int t[60], a[60], len;
    LL ans;
    
    void input()
    {
        scanf("%d", &n);
        len = n;
        for (int i = 0; i < len; ++i)
            scanf("%d", &t[i]);
        for (int i = 0; i < len; ++i)
        {
            if (t[i] == -1) continue;
            for (int j = 0; j < len; ++j)
            {
                if (i == j) continue;
                if (t[j] == -1) continue;
                if (t[j]%t[i] == 0) t[j] = -1;
            }
        }
        int top = 0;
        for (int i = 0; i < len; ++i)
            if (t[i] != -1)
                a[top++] = t[i];
        len = top;
        sort(a, a+len);
    }
    
    LL gcd(LL x, LL y)
    {
        LL r;
        while (y != 0)
        {
            r = y;
            y = x%y;
            x = r;
        }
        return x;
    }
    
    LL lcm(LL x, LL y)
    {
        return x/gcd(x, y)*y;
    }
    
    void dfs(int now, LL num, int sz)
    {
        if (now == len)
        {
            if (sz)
            {
                LL last = maxN/num;
                if (sz&1) ans -= last;
                else ans += last;
            }
            return;
        }
        if (num%a[now] == 0) return;
        dfs(now+1, num, sz);
        LL t = lcm(num, a[now]);
        if (t <= maxN) dfs(now+1, t, sz+1);
    }
    
    void work()
    {
        if (len == 1 && a[0] == 1) printf("0
    ");
        else
        {
            ans = maxN;
            dfs(0, 1, 0);
            cout << ans << endl;
        }
    }
    
    int main()
    {
        //freopen("test.in", "r", stdin);
        int T;
        scanf("%d", &T);
        for (int times = 1; times <= T; ++times)
        {
            input();
            work();
        }
        return 0;
    }
    View Code
  • 相关阅读:
    2019年CSP-J初赛试题(普及组)试题详解
    开放课件
    猴子选大王 (约瑟夫问题)
    后缀表达式转中缀表达式
    JDBC的使用
    JDBC
    MySQL第五天
    MySQL第四天
    MySQL第三天
    MySQL第二天
  • 原文地址:https://www.cnblogs.com/andyqsmart/p/5375266.html
Copyright © 2011-2022 走看看