小P的数学问题 分块打表

Posted 幽殇默

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了小P的数学问题 分块打表相关的知识,希望对你有一定的参考价值。

在这里插入图片描述
题目地址

数据范围很大,需要分块打表预处理。

#include<cstdio>
#include<iostream>
using namespace std;
typedef long long int LL;
const int mod=1e9+7;
const int N=1e5;
LL a[15]=
{1,457992974,107146451,373281933,559805077,154425679,
679209364,526226141,644158465,730342129};//1e5
LL b[15]=
{1,641102369,578095319,5832229,259081142,974067448,
316220877,690120224,251368199,980250487};//1e6
LL c[15]=
{1,682498929,491101308,76479948,723816384,
67347853,27368307,625544428,199888908,888050723};//1e7
LL d[15]=
{1,927880474,933245637,668123525,429277690,733333339
,724464507,957939114,203191898,586445753,698611116};//1e8
int main(void)
{
	
	int t; scanf("%d",&t);
	while(t--)
	{
		int n; scanf("%d",&n);
		LL ans=1;
		if(n<1e5)
		for(int i=1;i<=n;i++) ans=ans*i%mod;
		if(n>=1e5&&n<1e6) 
		{
			int k=n/1e5;
			ans=a[k];
			for(int i=k*1e5+1;i<=n;i++) ans=ans*i%mod;
		}
		if(n>=1e6&&n<1e7)
		{
			int k=n/1e6;
			ans=b[k];
			for(int i=k*1e6+1;i<=n;i++) ans=ans*i%mod;
		}
		if(n>=1e7&&n<1e8)
		{
			int k=n/1e7;
			ans=c[k];
			for(int i=k*1e7+1;i<=n;i++) ans=ans*i%mod;
		}
		if(n>=1e8)
		{
			int k=n/1e8;
			ans=d[k];
			for(int i=k*1e8+1;i<=n;i++) ans=ans*i%mod;
		}
		cout<<ans<<endl;
	}
	return 0;
}

以上是关于小P的数学问题 分块打表的主要内容,如果未能解决你的问题,请参考以下文章

HDU 6555 The Fool(打表&整除分块)

洛谷P3396- 哈希冲突 - 分块

HDU 6333 莫队分块 + 逆元打表求组合数

整除分块

hdu 3037 费马小定理+逆元求组合数+Lucas定理

ACM经验分享[转]