比赛 20110729 评测结果 AAAAAAAAAA
题目名称 sumcount 最终得分 100
用户昵称 .Xmz 运行时间 0.000 s
代码语言 C++ 内存使用 0.00 MiB
提交时间 2011-07-29 09:59:42
显示代码纯文本
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#define ll long long
using namespace std;

int n,a,b,mod;

int to[2000011],p[200011],pn;

void getprime()
{
	for (int i=2;i<=b;i++)
	{
		if (to[i]==0) p[++pn]=i;
		for (int j=1;j<=pn && p[j]*i<=b;j++)
		{
			to[p[j]*i]=p[j];
			if (i%p[j]==0) break;
		}
	}
}

int c[2000011];

long long calc(long long u,int x)
{
	long long re = 1;
	for (; x ; x>>=1)
	{
		if (x & 1) re = (re * u) % mod;
		u = (u * u) % mod;
	}
	return re;
}

long long C(int m)
{
	if (m<n) return 0;
	for (int i=2;i<=m;i++) c[i]++;
	for (int i=2;i<=n;i++) c[i]--;
	for (int i=2;i<=m-n;i++) c[i]--;
	long long re=1;
	for (int i=m;i>=2;--i)
	if (c[i])
	{
		if (to[i]) 
		{
			c[to[i]] += c[i];
			c[ i/to[i] ] += c[i];
		}
		else re = ( re * calc(i,c[i]) ) % mod;
		c[i]=0;
	}
	return re;
}

void solve()
{
	a+=n; b+=n;
	getprime();
	printf("%lld\n",( C(b) - C(a-1) + mod ) % mod );
}

int main()
{
	freopen("sumcount.in","r",stdin);
	freopen("sumcount.out","w",stdout);
	scanf("%d%d%d%d",&n,&a,&b,&mod);
	solve();
	return 0;
}