luogu P2613有理数取余

85 篇文章 0 订阅

题目描述

给出一个有理数 c=a/b,求 c mod19260817的值。
输入输出格式
输入格式:
一共两行。
第一行,一个整数 a 。
第二行,一个整数 b 。
输出格式:
一个整数,代表求余后的结果。如果无解,输出Angry!
输入输出样例
输入样例#1:
233
666
输出样例#1:
18595654
说明
对于所有数据, 0≤a,b≤10e10001

分析

诡异,c估计是小数,而小数取余……放弃,这时可将其变形:c=a*b-1,而根据同余定理,可变为c=a*b-2%19260817,注意数据,要用高精,时间:0ms。
上代码

#include<bits/stdc++.h>
using namespace std;
long long a,b,mod=19260817,aa=0,bb=0,c,len1=0,len2=0,al[10010],bl[10010];
char all[10010],bll[10010];
long long power(long long x,long long y){
    int r=1;
    while(y){
        if(y%2) r=r*x%mod;
        x=x*x%mod;
        y/=2;
    }
    return r%mod;
}
void qya(){
    long long num=0;
    for(int i=len1;i<=len1+8;i++) num=10*num+al[i];
    num%=mod;
    for(int i=len1+8;i>=len1;i--){
        int now=num%10;
        num/=10;
        al[i]=now;
    }
    for(int i=0;i<=8;i++)
        if(al[len1+i]!=0){
            len1+=i;
            break;
        }
}
void qyb(){
    long long num=0;
    for(int i=len2;i<=len2+8;i++) num=10*num+bl[i];
    num%=mod;
    for(int i=len2+8;i>=len2;i--) {
        int now=num%10;
        num/=10;
        bl[i]=now;
    }
    for(int i=0;i<=8;i++)
        if(bl[len2+i]!=0){
            len2+=i;
            break;
        }
}
signed main(){
    scanf("%s",all);
    scanf("%s",bll);
    a=strlen(all),b=strlen(bll);
    for(int i=0;i<a;i++) al[i]=all[i]-'0';
    for(int i=0;i<b;i++) bl[i]=bll[i]-'0';
    while(a-len1>=10) qya();
    while(b-len2>=10) qyb();
    for(int i=len1;i<a;i++) aa=aa*10+al[i];
    for(int i=len2;i<b;i++) bb=bb*10+bl[i];
    aa%=mod,bb%=mod;
    c=power(bb,mod-2);
    if(c==0){
        printf("Angry!\n");
        return 0;
    }
    printf("%lld\n",aa*c%mod);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值