weinan030416

导航

爬树的甲壳虫(扩展欧几里得算法)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 10;
const int MOD = 998244353;
ll x[maxn], y[maxn];

//快速幂模板
ll ksm(ll a, ll b, ll m)
{
    ll ans = 1;
    while(b)
    {
        if(b & 1)ans = ans * a % m;
        b >>= 1;
        a = a * a % m;
    }
    return ans;
}
//求模MOD意义下的x的逆元
ll inv(ll x)
{
    return ksm(x, MOD - 2, MOD);
}
//扩展欧几里得模板
//求解cx+dy = gcd(c, d)的解,返回值为gcd(c, d)
ll extgcd(ll c, ll d, ll&x, ll&y)
{
    ll g = c;
    if(d)
    {
       g = extgcd(d, c % d, y, x);
       y -= (c / d) * x;
    }
    else x = 1, y = 0;
    return g;
}

int main()
{
    int n;
    cin >> n;
    for(int i = 1; i <= n; i++)
        cin >> x[i] >> y[i];
    ll a = 0, b = 0;
    for(int i = n; i >= 1; i--)
    {
        ll p = x[i] * inv(y[i]) % MOD, p_1 = (y[i] - x[i]) * inv(y[i]) % MOD;
        a = (p + p_1 * a) % MOD;
        b = (1 + p_1 * b) % MOD;
    }
    //求解cx + dy = e
    ll c = a - 1, d = MOD, e = MOD - b, x, y;
    //先求解cx + dy = gcd(c, d)
    ll g = extgcd(c, d, x, y);
    //再求解cx + dy = e
    ll ans_x = x * e / g;
    cout<<(ans_x % MOD + MOD ) % MOD<<endl;
    return 0;
}

 不取模版本

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 10;
const int MOD = 998244353;
double x[maxn], y[maxn];

//快速幂模板
ll ksm(ll a, ll b, ll m)
{
    ll ans = 1;
    while(b)
    {
        if(b & 1)ans = ans * a % m;
        b >>= 1;
        a = a * a % m;
    }
    return ans;
}
//求模MOD意义下的x的逆元
ll inv(ll x)
{
    return ksm(x, MOD - 2, MOD);
}
//扩展欧几里得模板
//求解cx+dy = gcd(c, d)的解,返回值为gcd(c, d)
ll extgcd(ll c, ll d, ll&x, ll&y)
{
    ll g = c;
    if(d)
    {
       g = extgcd(d, c % d, y, x);
       y -= (c / d) * x;
    }
    else x = 1, y = 0;
    return g;
}

int main()
{
    int n;
    cin >> n;
    for(int i = 1; i <= n; i++)
        cin >> x[i] >> y[i];
    double a = 0, b = 0;
    for(int i = n; i >= 1; i--)
    {
        double p = x[i]/y[i] /* inv(y[i]) % MOD,*/,p_1 = (1-x[i]/y[i]) ;//* inv(y[i]) % MOD;
//        cout<<p<<" "<<p_1<<endl;
        a = (p + p_1 * a);// % MOD;
        b = (1 + p_1 * b) ;//% MOD;
        cout<<a<<" "<<b<<endl;
    }
    cout<<"结果"<<b/(1-a)<<endl;
//    3
//    1 2
//    3 5
//    7 11
//    cout<<187/8;
//    //求解cx + dy = e
//    ll c = a - 1, d = MOD, e = MOD - b, x, y;
//    //先求解cx + dy = gcd(c, d)
//    ll g = extgcd(c, d, x, y);
//    //再求解cx + dy = e
//    ll ans_x = x * e / g;
//    cout<<(ans_x % MOD + MOD ) % MOD<<endl;
    return 0;
}

其他人的代码

#include<bits/stdc++.h>
using namespace std;

const int MOD = 998244353;
const int maxn = 1e5 + 5;
typedef long long LL;
int x[maxn], y[maxn];

// 快速幂 a^n % P 
LL fpow(LL a, int n, int P){
    LL res = 1;
    while (n){
        if(n&1)
            res = res * a % P;
        a = (a * a) % P;
        n >>= 1;
    }
    return res;
}

int main(){
    int n;
    scanf("%d", &n);
    for (int i=1; i<=n; ++i){    
        scanf("%d%d", &x[i], &y[i]);
    }
    // 计算s(i)和ans = a_0,pre = s(i-1)
    int ans = 0, pre = 1;
    for (int i=1; i<=n; ++i){
        pre = 1LL * pre * y[n-i+1] % MOD 
        * fpow(y[n-i+1]-x[n-i+1], MOD-2, MOD) % MOD;  // y >= x
        ans = (1LL * ans + pre) % MOD;
    }
    printf("%d\n", ans);
    return 0;
} 

 

posted on 2023-02-08 23:18  楠030416  阅读(38)  评论(0编辑  收藏  举报