Codeforces 396B On Sum of Fractions 数论

题目链接:Codeforces
396B On Sum of Fractions

题解来自:http://blog.csdn.net/keshuai19940722/article/details/20076297

题目大意:给出一个n,ans = ∑(2≤i≤n)1/(v(i)*u(i)), v(i)为不大于i的最大素数,u(i)为大于i的最小素数, 求ans,输出以分式形式。

解题思路:一开始看到这道题1e9,暴力是不可能了,没什么思路,后来在纸上列了几项,突然想到高中时候求等差数列时候用到的方法,具体叫什么不记得了。

1/(2*3) = (1/2  - 1/3) * 1/(3-2);

1/(3*5) = (1/3 - 1/5) * 1/(5-3);

然后值为1/(2*3)的个数有(3-2)个,为1/(3*5)的有(5-3)个;

这样假设有n,v = v(n),  u = u(n);

1/(2*3) + 1/(3*5) * (5-3) + ...... + 1/(v*u) * (n-v+1)  (注意最后不是u-v个)

= 1/2 - 1/3 + 1/3 - 1/5 + ........ -1/v + 1/(v*u) *(n-v+1)

= 1/2 - 1/v + 1/(v*u)*(n-v+1)

p = u*v + 2*(n-v-u+1); q = 2*u*v;

记得约分,然后u和v就用枚举的方式。

学到:

1、求一个很大的数n的最接近他的素数,可以筛出sqrt(n)内的素数,然后,判断素数是不是n的约数---其实是借助了一对约数里,小的总是<=sqrt(n)

时间复杂度,<sqrt(n)时 O(1),>sqrt(n)时,O(n)

2、如果乍一看没发现规律或者没思路,自己模拟几个数,连续着模拟,别局限于Sample input,自己找找规律

int prmcnt;
bool is[N];int prm[M];
int getprm(int n)
{
    int i,j,k=0;
    int s,e=(int)(sqrt(0.0+n)+1);
    CL(is,1);
    prm[k++]=2;is[0]=is[1]=0;
    for(i=4;i<n;i+=2)is[i]=0;
    for(i=3;i<e;i+=2)
        if(is[i])
        {
            prm[k++]=i;
            for(s=i*2,j=i*i; j<n; j+=s)
                is[j]=0;
        }
    for(;i<n;i+=2)if(is[i])prm[k++]=i;
    return k;
}

bool judge(int x)
{
    if(x<MAXN-1)return is[x];
    for(int i=0;i<prmcnt;i++)
        if(x% prm[i] == 0)return 0;
    return 1;
}

AC代码

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <iostream>
#include <iomanip>
#include <cmath>
#include <map>
#include <set>
#include <queue>
using namespace std;

#define ls(rt) rt*2
#define rs(rt) rt*2+1
#define ll long long
#define ull unsigned long long
#define rep(i,s,e) for(int i=s;i<e;i++)
#define repe(i,s,e) for(int i=s;i<=e;i++)
#define CL(a,b) memset(a,b,sizeof(a))
#define IN(s) freopen(s,"r",stdin)
#define OUT(s) freopen(s,"w",stdout)

const ll ll_INF = ((ull)(-1))>>1;
const double EPS = 1e-8;
const int INF = 100000000;
const int MAXN = 1e5+5;
const int N = MAXN;
const int M=N;
int prmcnt;
bool is[N];int prm[M];
int getprm(int n)
{
    int i,j,k=0;
    int s,e=(int)(sqrt(0.0+n)+1);
    CL(is,1);
    prm[k++]=2;is[0]=is[1]=0;
    for(i=4;i<n;i+=2)is[i]=0;
    for(i=3;i<e;i+=2)
        if(is[i])
        {
            prm[k++]=i;
            for(s=i*2,j=i*i; j<n; j+=s)
                is[j]=0;
        }
    for(;i<n;i+=2)if(is[i])prm[k++]=i;
    return k;
}

bool judge(int x)
{
    if(x<MAXN-1)return is[x];
    for(int i=0;i<prmcnt;i++)
        if(x% prm[i] == 0)return 0;
    return 1;
}

int calv(int x)
{
    for(int i=x;i>1;i--)
        if(judge(i))return i;
    //
}
int calu(int x)
{
    for(int i=x+1;;i++)
        if(judge(i))return i;
}

ll gcd(ll x, ll y)
{
    return y == 0?x:gcd(y,x%y);
}

int main()
{
    prmcnt=getprm(MAXN-1);
    int ncase,n;
    scanf("%d",&ncase);
    while(ncase--)
    {
        scanf("%d",&n);
        ll v= calv(n);
        ll u= calu(n);
        ll up =v*u-2*u-2*v+2*n+2;
        ll down=2*v*u;
        ll tmp=gcd(up,down);
        up/=tmp;
        down/=tmp;
        cout << up << '/' << down << endl;
    }
    return 0;
}

Codeforces 396B On Sum of Fractions 数论,布布扣,bubuko.com

时间: 2024-10-12 14:32:48

Codeforces 396B On Sum of Fractions 数论的相关文章

Codeforces 396B On Sum of Fractions 规律题

题目链接:点击打开链接 我们把 1 / { u(i)*v(i) }拆开->  (1/(u(i)-v(i)) * ( 1/v(i) - 1/u(i) ) 若n +1  是素数,则显然(1/(u(i)-v(i)) * ( 1/v(i) - 1/u(i) ) 这样完全相同的式子有 u(i)-v(i) 个 那么就可以把前面系数约掉,那么剩下的式子就是 1/2 - 1/(n+1) 若不是,则我们找到第一个<=n的素数,即v(n) 和第一个>n的素数,即 u(n) 然后前面的 2-v(n)求和,即

codeforces 446C DZY Loves Fibonacci Numbers 数论+线段树成段更新

DZY Loves Fibonacci Numbers Time Limit:4000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit Status Appoint description:  System Crawler  (2014-07-14) Description In mathematical terms, the sequence Fn of Fibonacci numbers is defi

UVA 10791 Minimum Sum LCM (数论)

LCM (Least Common Multiple) of a set of integers is defined as the minimum number, which is a multiple of all integers of that set. It is interesting to note that any positive integer can be expressed as the LCM of a set of positive integers. For exa

GCD SUM 强大的数论,容斥定理

GCD SUM Time Limit: 8000/4000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others) SubmitStatus Problem Description 给出N,M执行如下程序:long long  ans = 0,ansx = 0,ansy = 0;for(int i = 1; i <= N; i ++)   for(int j = 1; j <= M; j ++)       if(gcd(i,j)

Codeforces 622F The Sum of the k-th Powers(数论)

题目链接 The Sum of the k-th Powers 其实我也不懂为什么这么做的--看了无数题解觉得好厉害哇-- 1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 #define rep(i, a, b) for (int i(a); i <= (b); ++i) 6 #define dec(i, a, b) for (int i(a); i >= (b); --i) 7 8 const int mod = 1

Codeforces 963A Alternating Sum 【数论+数学】

官方题解这个样子我觉得说得比较清楚.Z我们可以朴素的预处理出来(注意乘法膜),q的话考点在于[分数取膜]即 (a/b)%P = a* inverse of b %P 这就涉及到算b的逆元,我用的是欧几里得算法.下面这个博客写的很清楚. http://www.cnblogs.com/frog112111/archive/2012/08/19/2646012.html 然后还有两个细节,一是要写快速幂这样才能 O(k * log(n)) 复杂度预处理出Z,快速幂的时候注意a的类型得是long lon

CodeForces 743C Vladik and fractions (数论)

题意:给定n,求三个不同的数满足,2/n = 1/x + 1/y + 1/z. 析:首先1是没有解的,然后其他解都可以这样来表示 1/n, 1/(n+1), 1/(n*(n+1)),这三个解. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #include <cstdlib> #include <

Codeforces 121A Lucky Sum

Lucky Sum Time Limit: 2000ms Memory Limit: 262144KB This problem will be judged on CodeForces. Original ID: 121A64-bit integer IO format: %I64d      Java class name: (Any) Petya loves lucky numbers. Everybody knows that lucky numbers are positive int

codeforces 85D D. Sum of Medians Vector的妙用

D. Sum of Medians Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://codeforces.com/problemset/problem/85/D Description In one well-known algorithm of finding the k-th order statistics we should divide all elements into groups of five consecutive el