zoukankan      html  css  js  c++  java
  • 数学&数论的一些题

    Problem 1

    BZOJ 2440: [中山市选2011]完全平方数
    Time Limit: 10 Sec Memory Limit: 128 MB
    Submit: 5134 Solved: 2497

    Description

    小 X 自幼就很喜欢数。但奇怪的是,他十分讨厌完全平方数。他觉得这些数看起来很令人难受。由此,他也讨厌所有是完全平方数的正整数倍的数。然而这丝毫不影响他对其他数的热爱。
    这天是小X的生日,小 W 想送一个数给他作为生日礼物。当然他不能送一个小X讨厌的数。他列出了所有小X不讨厌的数,然后选取了第 K个数送给了小X。小X很开心地收下了。
    然而现在小 W 却记不起送给小X的是哪个数了。你能帮他一下吗?

    Input

    包含多组测试数据。文件第一行有一个整数 T,表示测试数据的组数。
    第2 至第T+1 行每行有一个整数Ki,描述一组数据,含义如题目中所描述。

    Output

    含T 行,分别对每组数据作出回答。第 i 行输出相应的第Ki 个不是完全平方数的正整数倍的数。

    Sample Input

    4
    1
    13
    100
    1234567

    Sample Output

    1
    19
    163
    2030745

    HINT

    对于 100%的数据有 1 ≤ Ki ≤ 10^9, T ≤ 50
    题目简意:求第k小不是完全平方数的数

    题解:

    无平方因子数,即分解质因数后所有质因数的次数都为1的数.
    从1开始第k个非完全平方数 ⇔ min(n),比n小的非完全平方数有k个。有了这个性质,可以二分答案。
    任何一个数都可以化成多个质因子相乘的形式
    那么一个完全平方数的倍数肯定至少有两个质因子是相等的
    我们设n以内的非完全平方数倍数的个数为ans,ans=n-完全平方数的个数
    想一想完全平方数倍数的个数怎么计算?
    发现我们只用找出2,3,5,7..质数的完全平方数倍数的个数就可以了,因为所有数都由他们组成 -n/(2*2)-n/(3*3)-n/(5*5)....
    但我们发现会重复减一些数,于是要进行容斥
    减含奇数个质数的完全平方数倍数的个数,加上含偶数个质数的完全平方倍数的个数(所有质因子都不相同,因为如果有相同肯定是其倍数,我们会在之前就减去掉的)

    于是发现它们加减规则和μ的规则一样
    即第n小非完全平方数的个数为:
    剩下二分答案就可以了

    #include<bits/stdc++.h>
    using namespace std;
    const int N=5e4+12;
    int prime[N],cnt,vis[N],mu[N];
    long long ans=0;
    void getmu()
    {
        mu[1]=1;
        for(int i=2;i<=N;i++) 
        {
            if(!vis[i]) prime[++cnt]=i,mu[i]=-1;//注意mu赋初值 
            for(int j=1;j<=cnt;j++) 
            {
                if(prime[j]*i>N) break;
                vis[prime[j]*i]=1;
                if(i%prime[j]==0) {mu[i*prime[j]]=0;break;}
                else mu[i*prime[j]]=-mu[i];
            }
        }
    }
    long long check(long long mid) 
    {
        long long res=0;
        long long t=sqrt(mid);
        for(int i=1;i<=t;i++) 
        res+=mid/(i*i)*mu[i];
        return res;
    }
    int main()
    {
        getmu();
        int T;
        scanf("%d",&T);
        while(T--) 
        {
            long long k;scanf("%lld",&k);
            long long l=k,r=1644934081,ans=0; 
            while(l<=r) 
            {
                long long mid=(l+r)>>1;
                if(check(mid)>=k) ans=mid,r=mid-1;
                else l=mid+1;
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
    

    Problem2

    [BZOJ1257][CQOI2007]余数之和

    (n,k≤10^9) 问题的数据规模较大,不能O(n)去求解。
    注意到[k/i]的取值最多只有2*sprt(k)个,且在连续一段区间上[k/i]的值是固定的,[k/i]*i是一个等差数列,所以可以按[k/i]分块,同一块内用等差数列直接算出每段的和

    #include <iostream>
    using namespace std;
    long long n, k, ans;
    int main() {
        cin >> n >> k; 
        ans = n * k;
        for (long long x = 1, gx; x<= n; x = gx + 1) 
        {
            gx = (k/x ? min(k/(k/x), n) : n);
            ans -= (k/x) * (x + gx) * (gx - x + 1) / 2;
        }
        cout << ans << endl;
        return 0;
    }  
    

    数论整除分块的思想推导

  • 相关阅读:
    184. Department Highest Salary【leetcode】sql,join on
    181. Employees Earning More Than Their Managers【leetcode】,sql,inner join ,where
    178. Rank Scores【leetcode】,sql
    177. Nth Highest Salary【leetcode】,第n高数值,sql,limit,offset
    176. Second Highest Salary【取表中第二高的值】,sql,limit,offset
    118. Pascal's Triangle【LeetCode】,java,算法,杨辉三角
    204. Count Primes【leetcode】java,算法,质数
    202. Happy Number【leetcode】java,hashSet,算法
    41. First Missing Positive【leetcode】寻找第一个丢失的整数,java,算法
    删除
  • 原文地址:https://www.cnblogs.com/tham/p/13472490.html
Copyright © 2011-2022 走看看