首页 > 代码库 > 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)求和,即 1/2 - 1/v(n)

后面共有 n - v(n)项,即 (n-v(n)) * (1/ (u(n)*(v(n) )

同分即可。

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<set>
#include<queue>
#include<map>
#include<vector>
using namespace std;
#define N 10000
#define ll __int64
inline ll gcd(ll x, ll y){
	if(x>y)swap(x,y);
	while(x){
		y %= x;
		swap(x,y);
	}
	return y;
}
ll prime[N],primenum;//有primenum个素数 math.h  
void PRIME(ll Max_Prime){  
    primenum=0;  
    prime[primenum++]=2;  
    for(ll i=3;i<=Max_Prime;i+=2)  
    for(ll j=0;j<primenum;j++)  
        if(i%prime[j]==0)break;  
        else if(prime[j]>sqrt((double)i) || j==primenum-1)  
        {  
            prime[primenum++]=i;  
            break;  
        }  
}  
bool Isprime(ll x){
	ll maxx = sqrt(x)+10;
	maxx = min(maxx, x);
	for(ll i = 1; i < primenum && prime[i]<maxx; i++)
		if(x%prime[i] == 0)return false;
	return true;
}
ll n;
ll Havprime(ll x, ll add){
	if(x==2)return x;
	if(!(x&1))x+=add;
	add <<= 1;
	while(1){
		if(Isprime(x))return x;
		x += add;
	}
}
ll s,x;
void go(ll u, ll v){
	if(v==u-1){
		s = u-2;	x = 2*u;
		return;
	}
	x = 2*u*v;
	s = u*v-2*u-2*v+2*n+2;
}
int main(){
	PRIME(100000);
	ll i, u, j, T;cin>>T;
	while(T--) {
		cin>>n;
		ll v = Havprime(n,-1), u = Havprime(n+1,1);
		go(u,v);
		ll _gcd = gcd(s,x);
		cout<<s/_gcd<<"/"<<x/_gcd<<endl;
	}
	return 0;
}