比赛 |
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;
}