比赛 20110729 评测结果 AWAWWTEETE
题目名称 sumcount 最终得分 20
用户昵称 苏轼 运行时间 0.000 s
代码语言 C++ 内存使用 0.00 MiB
提交时间 2011-07-29 10:45:24
显示代码纯文本
#include <cstdio>
#include <map>
#include <vector>
#include <algorithm>
using namespace std;

const int MAXN=2000005;
int MO;
typedef long long Int;
typedef pair<int,int> Pair;
#define pb push_back
#define mp make_pair

struct Node
{
	int l,r,mid,sum;
	Node *c[2];
	Node(int _l,int _r):l(_l),r(_r){mid=(l+r)/2;sum=1;c[0]=c[1]=NULL;}
	Node(){}
}pool[MAXN],*mem=pool;

int powmod(Int x,int n)
{
	x=x%MO;
	Int y=n%2?x:1;
	while(n>>=1)
	{
		x=x*x%MO;
		if (n%2)
			y=y*x%MO;
	}
	return y;
}

struct Tree
{
	Node *root;
	vector<Pair> all;
	void build(Node *&p,int l,int r)
	{
		p=new (mem++)Node(l,r);
		if (l==r)
		{
			p->sum=powmod(all[l].first,all[l].second);
			return ;
		}
		build(p->c[0],l,p->mid);
		build(p->c[1],p->mid+1,r);
		p->sum=(Int)p->c[0]->sum*p->c[1]->sum;
	}
	void init()
	{
		reverse(all.begin(),all.end());
		build(root,0,all.size()-1);
	}
	void insert(Node *p,int pos,int val)
	{
		if (p->l==p->r)
		{
			all[pos].second+=val;
			p->sum=powmod(all[pos].first,all[pos].second);
			return ;
		}
		if (pos<=p->mid)
			insert(p->c[0],pos,val);
		else
			insert(p->c[1],pos,val);
		p->sum=(Int)p->c[0]->sum*p->c[1]->sum%MO;
	}
	void insert(int pos,int val)
	{
		insert(root,pos,val);
	}
	Int getans()
	{
		return root->sum;
	}
}tree;

int N,M,A,B,tot;
int flag[MAXN],mul[MAXN];
vector<Pair> v[MAXN];
map<int,int> trans;

void init()
{
	for(int i=2;i<=M;i++)
		flag[i]=1;
	int tot=0;
	for(int i=2;i<=M;i++)
		if (flag[i]==1)
		{
			trans[i]=tot++;
			v[i].pb(mp(i,1));
			for(int j=i+i;j<=M;j+=i)
			{
				flag[j]=i;
				int k=j/i,t=1;
				while(k%i==0)
					k/=i,t++;
				v[j].pb(mp(i,t));
			}
		}
	for(int i=A+1;i<=A+N-1;i++)
		mul[i]++;
	for(int i=2;i<=N-1;i++)
		mul[i]--;
	for(int i=M;i>=2;i--)
		if (flag[i]!=1)
		{
			mul[flag[i]]+=mul[i];
			mul[i/flag[i]]+=mul[i];
			mul[i]=0;
		}
		else
			tree.all.pb(mp(i,mul[i]));
	tree.init();
}

inline void Add(int &a,int b)
{
	a=(a+b)%MO;
}

int main()
{
	freopen("sumcount.in","r",stdin);
	freopen("sumcount.out","w",stdout);
	scanf("%d%d%d%d",&N,&A,&B,&MO);
	M=B+N-1;
	init();
	int re=0;
	Add(re,tree.getans());
	vector<Pair>::iterator it;
	vector<Pair> *now;
	for(int i=A+1;i<=B;i++)
	{
		for(it=(now=&v[i+N-1])->begin();it!=now->end();it++)
			tree.insert(trans[it->first],it->second);
		for(it=(now=&v[i])->begin();it!=now->end();it++)
			tree.insert(trans[it->first],-it->second);
		Add(re,tree.getans());
	}
	printf("%d\n",re);
	return 0;
}