牛牛的算术(公式推导)

链接:https://ac.nowcoder.com/acm/contest/7079/B
来源:牛客网
 

时间限制:C/C++ 2秒,其他语言4秒
空间限制:C/C++ 524288K,其他语言1048576K
64bit IO Format: %lld

题目描述

牛牛最近学习了取模是什么 于是他看到了下面这一道题:

多次询问:每次询问包含一个正整数 nnn 要求你输出下列结果
∏i=1n∑j=1i∑k=1ji×j×k\prod_{i=1}^n \sum_{j=1}^i \sum_{k=1}^j i\times j\times k∏i=1n​∑j=1i​∑k=1j​i×j×k
为了避免结果过大 只需要输出这个式子对 199999199999199999(=2×32×41×271+1=2\times 3^2 \times 41 \times 271+1=2×32×41×271+1,一个质数) 取模的结果。

输入描述:

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

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

输出描述:

TTT 行非负整数 代表答案。

示例1

输入

复制5 1 2 3 4 5

5
1
2
3
4
5

输出

复制1 14 1050 73001 100955

1
14
1050
73001
100955

说明

n=2 的情况:(1*1*1)*(2*1*1+2*2*1+2*2*2) = 14

备注:

n≤10105n \leq 10^{10^5}n≤10105

保证输入总长度 ≤5×105\leq 5 \times 10^5≤5×105 且 T≤105T \leq 10^5T≤105

 


个人觉得唯一的难点在于刚开始的化简

关于这个怎么推出来的?我问了几个人,觉得目前能用的方法就是归纳,取n比较小的时候然后找规律去拆拆加加,当然数学好的当我没说。

如果出了这一步,那就预处理后面两个前缀,然后再处理一个连乘的sumi[i].

另外一个trick就是n很大,mod小,所以当n大于模数并且会枚举到mod的时候,后面的模数就都是0了(因为后面的都是模数的倍数)这个trick在多校里也有。

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=3e5+100;
const int mod=199999;
typedef long long LL;
LL sumk[mod],sumj[mod],sumi[mod];
char str[maxn];
void solve()
{
	cin>>str+1;LL len=strlen(str+1); 
	if(len>6) cout<<0<<endl;
	else
	{
		LL n=0;
		for(LL i=1;i<=strlen(str+1);i++){
			n=n*10+str[i]-'0';
		}
		if(n>=mod) cout<<0<<endl;
		else cout<<sumi[n]<<endl;
	}
} 
int main(void)
{
  sumi[0]=1;
  for(LL k=1;k<=mod;k++)  sumk[k]=(sumk[k-1]%mod+k%mod)%mod;
  for(LL j=1;j<=mod;j++)  sumj[j]=(sumj[j-1]%mod+sumk[j]%mod*j%mod)%mod;
  for(LL i=1;i<=mod;i++)  sumi[i]=(sumi[i-1]%mod*i%mod*sumj[i]%mod)%mod;
  LL t;cin>>t;
  while(t--)
  {
  	solve();
  	
  }
return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值