比赛 20110729 评测结果 ATTTTTTTTT
题目名称 sumcount 最终得分 10
用户昵称 PurpleShadow 运行时间 0.000 s
代码语言 C++ 内存使用 0.00 MiB
提交时间 2011-07-29 11:23:14
显示代码纯文本
#include <cstdio>
#include <vector>
#include <cstring>
using namespace std;
const int N=1000010;
int n,a,b,MOD;
vector<int> Prime[N*2];
void prepare(int n)
{
	static bool flag[N*2];
	static int tmp[N*2];
	memset(flag,0,sizeof(flag));
	int i,j;
	for (i=1;i<=n;++i) tmp[i]=i;
	flag[0]=flag[1]=1;
	for (i=2;i<=n;++i)
		if (!flag[i])
			for (j=i+i;j<=n;j+=i)
			{
				while (tmp[j]%i==0)
				{
					Prime[j].push_back(i);
					tmp[j]/=i;
				}
				flag[j]=1;
			}
	for (i=1;i<=n;++i)
		if (tmp[i]!=1) Prime[i].push_back(tmp[i]);
}
void init()
{
	scanf("%d%d%d%d",&n,&a,&b,&MOD);
	prepare(n+b-1);
}
typedef vector<int>::iterator vt;
struct Treap
{
	struct node
	{
		int mul,key;
		char times;
		node* c[2];
		node(const int &_key=0)
		{
			mul=key=_key;
			times=1;
		}
	};
	node* root,*null;
	Treap()
	{
		null=new node();
		null->mul=1;
		root=null;
	}
	inline int pow(int a,int b,int c)
	{
		long long ans=1,tmp=a;
		for (;;)
		{
			if (b&1) ans=(ans*tmp)%c;
			b>>=1;
			if (!b) break;
			tmp=(tmp*tmp)%c;
		}
		return ans;
	}
	inline void update(node *p)
	{
		p->mul=((long long)p->c[0]->mul*p->c[1]->mul%MOD*pow(p->key,p->times,MOD))%MOD;
	}
	void insert(int key,int c,node* &p)
	{
		if (p==null)
		{
			p=new node(key);
			p->c[0]=p->c[1]=null;
			return;
		}
		else
		{
			if (key<p->key) insert(key,c,p->c[0]);else
			if (key>p->key) insert(key,c,
				p->c[1]);else
			p->times+=c;
			update(p);
		}
	}
	void Ins(int key)
	{insert(key,1,root);}
	void Del(int key)
	{insert(key,-1,root);}
	int Mul()
	{return root->mul;}
};
Treap ans;
void solve()
{
	int i;
	for (i=a+1;i<=n+a-1;++i)
		for (vt j=Prime[i].begin();j!=Prime[i].end();++j)
			ans.Ins(*j);
	for (i=1;i<=n-1;++i)
		for (vt j=Prime[i].begin();j!=Prime[i].end();++j)
			ans.Del(*j);
	int Ans=ans.Mul();
	for (i=a+1;i<=b;++i)
	{
		for (vt j=Prime[n+i-1].begin();j!=Prime[n+i-1].end();++j)
			ans.Ins(*j);
		for (vt j=Prime[i].begin();j!=Prime[i].end();++j)
			ans.Del(*j);
		Ans=(Ans+ans.Mul())%MOD;
	}
	printf("%d\n",Ans);
}
int main()
{
freopen("sumcount.in","r",stdin);
freopen("sumcount.out","w",stdout);
	init();
	solve();
	return 0;
}