首页 > 其他分享 >P8584 探索未知 题解

P8584 探索未知 题解

时间:2023-05-25 21:56:33浏览次数:44  
标签:ch gcd int 题解 fz P8584 times 未知 define

题意

给你 \(n\) 个分数,每个分数后面跟着一个操作符 \(op\) , 如果为 \(1\) 就是加上这个分数,是 \(2\) 就减去。初始时是 \(0\) , 询问 \(n\) 次操作后最后的分数是多少,化成最简分数。

特殊地,如果最后是个整数,直接以整数的形式输出。

思路

模拟

考试的时候一看就想到了 [NOIP2020]排水系统,只不过这个题很良心,保证计算的时候不会出现 $2 \times 10^9 $ 以上的数,所以可以不用写高精或者是用 __int128

  • 首先我们要有最基础的数论知识:

    用 \(\gcd(a,b)\) 表示 \(a\) 和 \(b\) 的最大公约数,用 \(\text{lcm}(a,b)\) 表示 \(a\) 和 \(b\) 的最小公倍数。

    性质一:\(\gcd(a,b) = \gcd(b,a\% b)\) ,有了这个性质,我们就可以快速求出 \(a\) 和 \(b\) 的最大公约数,至于它的证明,我觉得这篇博客写的就很不错。

    性质二:\(\text{lcm}(a,b) = a \times b / \gcd(a,b)\)

    证明:由唯一分解定理可得

    我们设 \(a = p_1^{a_1} \times p_2^{a_2}\times \dots \times p_m^{a_m}\),

    \(b = p_1^{b_1} \times p_2^{b_2}\times \dots \times p_m^{b_m}(a_i,b_i \ge 0)\)。

    \(\therefore\) \(a \times b = p_1^{a_1+b_1}p_2^{a_2+b_2}\dots p_m^{a_m+b_m}\)

    $ = p_1^{\min(a_1,b_1)+\max(a_1,b_1)}\dots p_m^{\min(a_m,b_m)+\max(a_m,b_m)}$

    $ = \gcd(a,b) \times \text{lcm}(a,b)$

    证毕。

    有了这两个性质,我们就可以很好的求出两个数的最大公约数和最小公倍数了。

  • 接下来,模拟即可。可以通过代码来理解。

代码实现

#include<bits/stdc++.h>
#define int long long
#define ll long long
#define next nxt
#define re register
#define il inline

using namespace std;
int max(int x,int y){return x > y ? x : y;}
int min(int x,int y){return x < y ? x : y;}

int n,fz,fm,nfz,nfm;
int op;

il int read()
{
    int f=0,s=0;
    char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) f |= (ch=='-');
    for(; isdigit(ch);ch=getchar()) s = (s<<1) + (s<<3) + (ch^48);
    return f ? -s : s;
}

il int gcd(int a,int b) { return b ? gcd(b,a%b) : a; }
il int lcm(int a,int b) { return a*b/gcd(a,b); }
il int Abs(int x) { return x < 0 ? -x : x; }

signed main()
{
    n = read() - 1;
    fz = read() , fm = read() , op = read();/*首先录入第一个分数*/
    if(op == 2) fz = -fz;/*是减法的话,让分子变为负数*/
    for(re int i=1;i<=n;i++)
    {
        nfz = read() , nfm = read() , op = read();/*输入新分子和分母*/
        if(fz == 0) { if(op == 2) fz = -nfz; else fz = nfz ; fm = nfm; continue; }/*如果原先的数是0,那么直接重新赋值即可*/
        int Lcm = lcm(fm,nfm);/*找到分母的最小公倍数*/
        //cout << Lcm << endl;
        fz *= (Lcm/fm) , nfz *= (Lcm/nfm);/*分子乘上分母变成最小公倍数的倍数*/
        //cout << fz << " " << nfz << " ";
        if(op == 1) fz+=nfz; else fz-=nfz;/*分母相等,可以对分子做加减运算*/
        fm = Lcm;/*分母变成最小公倍数*/
        int Gcd = \gcd(Abs(fz),fm);/*给分数约分,注意分子可能为负数,所以要用绝对值找最大公因数*/
        fz /= Gcd; fm /= Gcd;
    }
    if(fz%fm == 0)/*如果是整数*/
    {
        if(fz < 0)
        printf("-%lld",Abs(fz)/\gcd(Abs(fz),fm));/*小于0加负号*/
        if(fz == 0) printf("0");/*分子是0输出0*/
        if(fz > 0) /*大于不用负号*/
        printf("%lld",fz/\gcd(fz,fm));
    }
    else printf("%lld/%lld",fz,fm);/*分数直接输出*/
    return 0;
}

时间复杂度 \(\Theta(n\log n)\) ,可以通过。

自认为写的很详细了,有什么问题可以在评论区问。

标签:ch,gcd,int,题解,fz,P8584,times,未知,define
From: https://www.cnblogs.com/bloodstalk/p/17433069.html

相关文章

  • P8587 新的家乡 题解
    题意给定\(n\)个高度分别为\(h_i\)的柱子,两个柱子能合并成一个\(h_i+h_j\)的新柱子,每根柱子至多被使用一次。询问最多能建出多少根高度相同的柱子,并且最优答案下柱子的高度有多少种情况。\(1\leqn\leq10^6\),\(1\leqh_i\leq3\times10^3\)。思路爆搜!首先我们......
  • P8585 球状精灵的传说 题解
    很好的一个题题意给你\(n\)个三元组\((r_1,r_2,r_3)\),并定义\(ρ=\lfloor\frac{1}{4}min(r_1,r_2,r_3)^3\rfloor\)。两个三元组能合并当且仅当这两个三元组有至少两个值相同,即从\((x_1,y,z)\)和\((x_2,y,z)\)变为\((x_1+x_2,y,z)\)。\((x,y,z)\)的位置不固定......
  • Android 修改 android/hardware/interfaces 下HIDL接口编译报异常问题解决
    最近要增加hostapd的一个HIDL接口,修改android/hardware/interfaces/wifi/hostapd/1.2/IHostapd.hal文件后编译报错如下:ERROR:[email protected]::IHostapdhashashacaed0a159a521bd4964e0fb8117320849109d3eeaff6a08b4d2506156ce6987whichdoesnotmatch......
  • P2480 古代猪文 题解
    题意:求\[g^{\sum_{k\midn}{n\choosek}}\]对\(999911659\)取模。\(1\len,g\le10^9\)。思路:首先根据欧拉定理,题目转化为求\(\displaystyle\sum_{k\midn}{n\choosek}\)对\(999911658\)取模的值。模数为合数不是很好做,因式分解发现\(999911658=2\times3\times467......
  • JOISC 2021 题解
    JOISC21フードコート(FoodCourt)首先我们发现我们这个删除实际上可以假删除,我们每次问询时求出这个队列目前被删了几个(维护区间加,区间\(\max(0,A-x)\))就可以把删除操作给弄掉了。然后我们考虑对商店做扫描线!因为我们现在其实就是对商店的单点问询,我们这个加入操作也可以在左......
  • 【题解】Codeforces Round 737 (CF1557)
    VP情况:solve:4/5rank:431st评价:VP了一下,我这个shaberB直接5发罚时,耽误了二十多分钟,以及被D各种细节差点搞死。A.EzzatandTwoSubsequences(*800)题目描述:给定一个序列,将其分为\(2\)个组,要求这两个组的平均值之和最大,组内的数不要求在原序列中连续。题目分析:我们......
  • 【题解】CF1062E Company
    传送门先考虑如何求解区间LCA假设要我们求\(8\sim11\)的LCA。那么显然它们的LCA等效于8和11的LCA。发现8和11刚好是“最左”和“最右”的两个顶点,感性理解一下,就可以得出一个结论:区间LCA和dfs序最小的和最大的的LCA是等效的。(这个结论应该还......
  • 题解(教主的魔法)P2801
    题目教主的魔法题目描述教主最近学会了一种神奇的魔法,能够使人长高。于是他准备演示给XMYZ信息组每个英雄看。于是$N$个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为$1,2,\ldots,N$。每个人的身高一开始都是不超过$1000$的正整数。教主的魔法每次可以把闭区......
  • 常见问题解决 --- 安卓中一个类中的匿名类和另一个类中的匿名类无法相互传值
      runOnUiThread(newRunnable(){@Overridepublicvoidrun(){//在UI线程中执行的主代码textView.setText("Hello,world!");}});将上面更新主ui放置在匿名内部类的回调方法里即可传值给属性。......
  • AtCoder Beginner Contest 302 H. Ball Collector 题解
    AtCoderBeginnerContest302H.BallCollector题意跳过。可以视作将\(a_i,b_i\)之间连了一条边,然后\(a_i,b_i\)之间只能选一个等价于对于一条边只能选择其一个端点。那么对于只包含树的联通块而言,如果都选择儿子节点,那么会有一个根节点无法被选择上;而对于包含至少一个......