ZCMU-1254-GCC

1254: GCC

Time Limit: 1 Sec   Memory Limit: 128 MB
Submit: 54   Solved: 20
[ Submit][ Status][ Web Board]

Description

The GNU Compiler Collection (usually shortened to GCC) is a compiler system produced by the GNU Project supporting various programming languages. But it doesn’t contains the math operator “!”.
In mathematics the symbol represents the factorial operation. The expression n! means "the product of the integers from 1 to n". For example, 4! (read four factorial) is 4 × 3 × 2 × 1 = 24. (0! is defined as 1, which is a neutral element in multiplication, not multiplied by anything.)
We want you to help us with this formation: (0! + 1! + 2! + 3! + 4! + ... + n!)%m
 

Input

The first line consists of an integer T, indicating the number of test cases.
Each test on a single consists of two integer n and m.

Output

Output the answer of (0! + 1! + 2! + 3! + 4! + ... + n!)%m.

Constrains
0 < T <= 20
0 <= n < 10^100 (without leading zero)
0 < m < 1000000

Sample Input

1
10 861017

Sample Output

593846

【解析】
这道题又是大型数据,刚刚看到就头痛,这道题肯定需要优化肯定有点规律不然肯定做不了...那我们就想啊,m最大
也就是100万,但是n居然可以是10的100次方,而且我们还要算阶乘,这个数是巨大的我们肯定要用字符串来存储了。
然后呢我们想啊,如果我们的n都大于m的话,比如说我们的m是100001,而n是100010那么我们算只用算到100000就够了
为什么?因为100001之后的阶乘一取余就是0,我这里也说一下概念比如说我们(7+3)%2我们可以先让7%2再和3相加再取
余2这显然是可以的所以这里就用到这个思想来进行处理。这里呢只要当输入的n的长度超过了7就表示他肯定已经超过了
m了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
using namespace std;
int main()
{
    int t,i;
    long long m;
    scanf("%d",&t);
    while(t--)
    {
        long long num=0,sum=1,p=1;
        char s[200];
        scanf("%s%lld",s,&m);
        if(strlen(s)>7)//判断是否比最大的m大了
        {
            num=m-1;
        }
        else
        {
            for(i=0;s[i]!='\0';i++)
            {
                num=num*10+s[i]-'0';//如果m没有超过7位数,我们就直接计算出来
            }
            if (num>=m)
                num=m-1;//比m大也只到m-1为止
        }
        for(i=1;i<=num;i++)
        {
            p=(p*i)%m;//进行取余运算了
            sum=(sum+p)%m;
        }
        sum=sum%m;
        printf("%d\n",sum);
    }
    return 0;
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值