Topic Links:
http://poj.org/problem?id=2773
Main topic:
Give you two integers of N and K. Find the number of K-and N-Biotin (the number of the biotin is arranged from small to large). Of
(1 <= m <= 1000000,1 <= K <= 100000000).
Problem Solving Ideas:
K is very large, directly from small to large enumeration to find unrealistic, can only be two-point answer. Two-minute enumeration [1. INF], the total number of x in the range
Find the number of 1~x in the range of N-biotin. Assuming that equals k is the result.
Then consider the number of 1~x within the range of n-ary = x-1~x in the range of n-ary
The number of 1~x in the range and n is calculated using a simple repulsion theorem.
AC Code:
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include < Cmath> #define LL __int64using namespace Std;const ll INF = 0xfffffff0;int prime[1000010],ct,n;void Divide () {ct = 0; int n = n; for (int i = 2; I <= sqrt (n*1.0); ++i) {if (n% i = = 0) {prime[ct++] = i; while (n% i = = 0) n/= i; }} if (n! = 1) prime[ct++] = n;} ll Solve (int n) {ll ans = 0; for (int i = 1; i < (1 << CT); ++i) {LL odd = 0; LL tmp = 1; for (int j = 0; j < ct; ++j) {if ((1 << j) & i) {odd++; TMP *= PRIME[J]; }} if (Odd & 1) ans + = n/tmp; else ans-= n/tmp; } return N-ans;} int main () {int K; while (~SCANF ("%d%d", &n,&k)) {Divide (); LL left = 1, right = INF, Mid, TMP; while (LEFT < right)//two points answer {Mid = (left + right) >> 1; TMP = Solve (Mid); if (TMP >= K) right = Mid; else left = Mid + 1; } printf ("%i64d\n", left); } return 0;}
POJ2773 Happy 2006 "The principle of tolerance and repulsion"