zoukankan      html  css  js  c++  java
  • 8.7-Day1T1

    题目大意:

    T组测试数据,每组测试数据给出一个n,求[0,n-1]所有逆元的和。(n可能不为质数)

     

    题解:

    我的想法:

    求出每一个数的逆元,再相加。由于有n为质数的时候,所以,我将它分为两种情况:(1)n为质数是,线性求逆元(2)n不为质数时,扩展欧几里得求逆元

    理论上可以拿个60分的...但我数组开大了,,,文件直接不可运行了...爆零...

    正解:

    算法1:

    n是质数的时候,所有数都有质数,直接输出n * (n - 1) / 2;

    算法2:

    n不是质数的时候,判断一下逆元是否存在,然后累加即可;

    判断存在用 gcd(i,n)=1 就可以, O(logn)

    求逆元可以利用扩展欧几里得求逆元,O(logn)

    算法3:

    这道题有两个性质:

    性质 1:集合{[0,n-1]中存在逆元的数}==集合{[0,n-1]中存在逆元的数的逆元}

    性质 2:[0,n-1]中与互质的数的和为 n*(n)/2 

    性质 1 的正确性:

    因为对逆元再求逆元得到的是本身,它们就是一一对应的了;

    这样问题就转化成了求[0,n-1]中与 n 互质的数的和;

    性质 2 是因为 gcd(n,i)=gcd(n,n-i)

    所以与 n 互质的数可以关于 n/2 对称的,也就是相加等于 n

    那答案为 n*(n)/2 也是显然了;

    复杂度为求欧拉的复杂度,O( sqrt(n) )

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<iostream>
    #define ll long long
    using namespace std;
    inline int read()
    {
        int sum = 0, p = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9')
        {
            if(ch == '-')
                p = -1;
            ch = getchar();
        }
        while(ch >= '0' && ch <= '9')
        {
            (sum *= 10) += ch - '0';
            ch = getchar();
        }
        return sum * p;
    }
    int phi(int x)
    {
        int cnt = x;
        for(int i = 2; i * i <= x; i++)
        {
            if(x % i == 0)
            {
                cnt /= i;
                cnt *= i - 1;
                while(x % i == 0)
                    x /= i;
            }
        }
        if(x != 1)
            cnt /= x,cnt *= x - 1;
        return cnt;
    }
    
    int main()
    {
        int n;
        int t = read();
        while(t--)
        {
            n = read();
            printf("%lld
    ",(ll)n * phi(n) / 2);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    MS SQL Server获取月份名称缩写
    视频站点程序
    视频站点程序 Ver2
    Infor Syteline 数据库增长月报表
    判断是否有选择RadioButtonList
    获取用户控件中控件的ID
    FileUpload上传图片前首先预览一下
    为TextBox装饰水印
    导航条的重构
    用户自己排序记录
  • 原文地址:https://www.cnblogs.com/darlingroot/p/11320592.html
Copyright © 2011-2022 走看看