牛客练习赛68 B.牛牛的算术

牛客练习赛68 B.牛牛的算术

题目链接

题目描述

牛牛最近学习了取模是什么 于是他看到了下面这一道题:
多次询问:每次询问包含一个正整数 n 要求你输出下列结果
∏ i = 1 n ∑ j = 1 i ∑ k = 1 j i × j × k \prod_{i=1}^n \sum_{j=1}^i \sum_{k=1}^j i\times j\times k i=1nj=1ik=1ji×j×k
为了避免结果过大 只需要输出这个式子对 199999(= 2 × 3 2 × 41 × 271 + 1 2\times 3^2 \times 41 \times271+1 2×32×41×271+1,一个质数) 取模的结果。

输入描述:

第一行一个正整数 T 表示询问次数。

接下来 T 行 每行一个正整数 n 含义如上所述

输出描述:

T 行非负整数 代表答案。

示例1

输入

5
1
2
3
4
5

输出

1
14
1050
73001
100955

直接打表找规律肯定找不到,出题人没那么憨,但是我们可以找后面那个 ∑ j = 1 i ∑ k = 1 j j × k \sum_{j=1}^i \sum_{k=1}^j j\times k j=1ik=1jj×k 的规律,很容易发现:
a [ i ] = i ∗ ( 1 + i ) ∗ ( 2 + i ) ∗ ( 1 + 3 ∗ i ) 24 a[i]=\frac{i*(1+i)*(2+i)*(1+3*i)}{24} a[i]=24i(1+i)(2+i)(1+3i)
看一下模数就可以预处理出 2 e 5 2e5 2e5 的答案,其余肯定都是 0 0 0。注意题目输入会很大,所以只能用字符串读入,AC代码如下:

#include
using namespace std;
typedef long long ll;
const int N=1e6+5;
const ll mod=199999;
ll power(ll a,ll b){
     return b?power(a*a%mod,b/2)*(b%2?a:1)%mod:1;}
ll ans[N];
void init(){
     
    ans[1]=1;
    for(ll i=2;i<N;i++){
     
        ll u=i*i%mod*(1+i)%mod*(2+i)%mod*(1+3*i)%mod*power(24,mod-2);
        ans[i]=u*ans[i-1]%mod;
    }
}

int main(){
     
    init();
    char s[N];
    int t;
    scanf("%d",&t);
    while(t--){
     
        scanf("%s",s);
        if(strlen(s)>6) printf("0\n");
        else{
     
            int u=0,len=strlen(s);
            for(int i=0;i<len;i++) u=u*10+(s[i]-'0');
            printf("%lld\n",ans[u]);
        }
    }
}

你可能感兴趣的:(数论,牛客,找规律)