LOJ6368:请让本题永远沉睡于此——题解

https://loj.ac/problem/6368

给一个分数,求对p=1e9+7取模的值。

给高一同学出的毒瘤模拟题,正好试试给loj传题,竟然过审了,虽然个人觉得很水,但是考试情况来看仅有一人得到了21分的好成绩

可能坑有点多。

1.作为一个不细心的普及组选手如何得到0pts的好成绩

这这这不是水就能过吗?

费马小定理或扩欧求逆元不就可以了吗。

emmm高精度太难写,弃了吧。

反正51pts够了。

 

2.作为一个不细心的提高组选手只会做D1T1如何得到0pts的好成绩

这这这不是水就能过吗?

费马小定理或扩欧求逆元不就可以了吗。

高精度不就是a*b^(p-2)%p=a*(b%p)^(p-2)吗?

就敲一个高精除低精就行了。

100pts美滋滋。

 

3.作为一个不太细心的普及组选手如何得到21pts的好成绩

这这这不是水就能过吗?

费马小定理或扩欧求逆元不就可以了吗。

emm把分母为0的情况特盘掉,然后看一下提示。

woc出题人良心大大的坏,需要把负号提出来,不然第二个样例会输出500000003。

这样应该就有51pts了吧。

 

4.作为一个细心的普及组选手如何得到51pts的好成绩

咦30pts的包也不需要高精啊为什么单独拿出来呢?

哦如果分母是p的倍数的话不就没有逆元就无解了吗?

等等还要特判分子分母都有p这个因子的情况。

哇真的有51pts啊!

 

5.作为一个细心的提高组选手只会做D1T1如何得到100pts的好成绩

高精度的话有可能分子和分母有多个p因子。

那么我就暴力对上下同时除p直到有余数为止。(因为二者都是0说明可能还没有除尽)

判断分母余数为0且分子不为0就无解。

否则就费马小定理/扩欧计算即可。

100pts轻松到手。

 

代码有点丑,也懒得改写了。

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
typedef long long ll;
const ll p=1e9+7;
ll qpow(ll k,ll n){
    if(n==0)return 1;
    if(n==1)return k%p;
    ll h=qpow(k,n/2)%p;
    if(n%2==0)return h%p*h%p;
    return h%p*h%p*k%p;
}
char a[10010],b[10010];
ll c[10010],d[10010];
ll g[10010],h[10010];
ll e1=0,e2=0;
int s1,s2;
bool w=1;
inline void init(){
    scanf("%s%s",a,b);
    if(a[0]=='-'){
        s1=strlen(a)-2;
        w=1-w;
        for(int i=0;i<=s1;i++){
            c[i]=a[i+1]-'0';
        }
    }else{
        s1=strlen(a)-1;
        for(int i=0;i<=s1;i++){
            c[i]=a[i]-'0';
        }
    }
    if(b[0]=='-'){
        s2=strlen(b)-2;
        w=1-w;
        for(int i=0;i<=s2;i++){
            d[i]=b[i+1]-'0';
        }
    }else{
        s2=strlen(b)-1;
        for(int i=0;i<=s2;i++){
            d[i]=b[i]-'0';
        }
    }
    return;
}
int main(){
    init();
    if(s2==0&&d[0]==0){
        printf("No Solution!\n");
        return 0;
    }
    if(s1==0&&c[0]==0){
        printf("0\n");
        return 0;
    }
    while(e1==0&&e2==0){
        int l1=-1,l2=-1;
        for(int i=0;i<=s1;i++){
            e1*=10;
            e1+=c[i];
            if(e1>=p){
                l1++;
                g[l1]=e1/p;
                e1%=p;
            }else if(l1!=-1){
                l1++;
                g[l1]=0;
            }
        }
        for(int i=0;i<=s2;i++){
            e2*=10;
            e2+=d[i];
            if(e2>=p){
                l2++;
                h[l2]=e2/p;
                e2%=p;
            }else if(l2!=-1){
                l2++;
                h[l2]=0;
            }
        }
        s1=l1;s2=l2;
        for(int i=0;i<=s1;i++)c[i]=g[i];
        for(int i=0;i<=s2;i++)d[i]=h[i];
    }
    if(e2==0&&e1!=0){
        printf("No Solution!\n");
        return 0;
    }
    ll ans=e1%p*qpow(e2,p-2)%p;
    if(!w&&ans)putchar('-');
    printf("%lld\n",ans);
    return 0;
}

+++++++++++++++++++++++++++++++++++++++++++

+本文作者:luyouqi233。               +

+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++

posted @ 2018-04-14 08:03  luyouqi233  阅读(738)  评论(0编辑  收藏  举报