This is most useful CP problem I create until now

Правка en2, от dreamoon_love_AA, 2019-12-27 19:35:04

After Educational Codeforces Round 79, I want to share a problem I create this year.

It's host on 2019 Multi-University Training Contest 5.

Problem link is here.

The statement of problem is following:

Many problems require printing the probability of something. Moreover, it is common that if the answer is $$$\frac{a}{b}$$$, you should output $$$a \times b^{-1} \pmod{p}$$$ ($$$p$$$ is a prime number). In these problems, you cannot know the exact value of the probability. It's so confusing!!! Now, we want to reverse engineer the exact probability from such calculated output value x. We do so by guessing the probability is the one with the minimum $$$b$$$ such that $$$a \times b^{-1} = x \pmod{p}$$$. Now we invite you to solve this problem with us!

What the statement mentioning is quite match the situation in contest of today!

The following is the reference solution (you can use the code to get the correct fraction format output in today contest):

#include<bits/stdc++.h>
using namespace std;
#define F first
#define S second
typedef long long LL;
typedef pair<LL,LL> PLL;
const int SIZE = 1e6+10;
PLL solveWA(LL x0, LL p){
    PLL r; 
    r.S = p / x0 + 1;
    r.F = r.S * x0 - p;
    PLL x = {x0, 1LL};
    while(r.F >= r.S) {
        if(r.F * 2 < x.F) {
            PLL nxt_r = make_pair((x.F / r.F + 1) * r.F - x.F , (x.F / r.F + 1) * r.S - x.S);
            x = r;
            r = nxt_r;
        }
        else {
            LL dif = x.F - r.F;
            LL tt = x.F / dif;
            // x.F - i * dif < r.S * i - x.S * (i-1)
            // x.F - x.S < (r.S + dif - x.S) * i
            LL need = (x.F - x.S) / (r.S + dif - x.S) + 1;
            if(need <= tt) return {x.F - need * dif, (r.S - x.S) * need + x.S};
            PLL nxt_r = {x.F - tt * dif, (r.S - x.S) * tt + x.S};
            x = r;
            r = nxt_r;
        }
    }
    return r;
}
PLL solveAC(LL x0, LL p){
    PLL r; 
    r.S = p / x0 + 1;
    r.F = r.S * x0 - p;
    PLL x = {x0, 1LL};
    while(r.F >= r.S) {
        if(r.F * 2 < x.F) {
            PLL nxt_r = make_pair((x.F / r.F + 1) * r.F - x.F , (x.F / r.F + 1) * r.S - x.S);
            x = r;
            r = nxt_r;
        }
        else {
            LL dif = x.F - r.F;
            LL tt = x.F / dif;
            // x.F - i * dif < r.S * i - x.S * (i-1)
            // x.F - x.S < (r.S + dif - x.S) * i
            LL need = (x.F - x.S) / (r.S + dif - x.S) + 1;
            if(need <= tt) return {x.F - need * dif, (r.S - x.S) * need + x.S};
            PLL nxt_r = {x.F - tt * dif, (r.S - x.S) * tt + x.S};
            x = {x.F - (tt - 1) * dif, (r.S - x.S) * (tt - 1) + x.S};
            r = nxt_r;
        }
    }
    return r;
}
LL modmul(LL A,LL B,LL mod)
{
    return (A*B-(LL)((long double)A*B/mod)*mod+mod)%mod;
}
int main(){
    int T;
    scanf("%d", &T);
    while(T--) {
        LL p, x;
        scanf("%lld%lld", &p, &x);
        PLL ret=solveAC(x,p);
        printf("%lld/%lld\n",ret.F,ret.S);
    }
    return 0;
}

История

 
 
 
 
Правки
 
 
  Rev. Язык Кто Когда Δ Комментарий
en2 Английский dreamoon_love_AA 2019-12-27 19:35:04 3168 Tiny change: '=source). [Problem l' -> '=source). \n\n[Problem l' (published)
en1 Английский dreamoon_love_AA 2019-12-27 18:38:34 138 Initial revision (saved to drafts)