单调队列,双向队列用法,虽然我觉得用线段树也能做(大概率超时,卡时间很严)
while(!q.empty()&&num[q.back()]>=num[i])
q.pop_back();//把大于等于他的全部删除,没用了。。。。
q.push_back(i);//放入
while(!q.empty()&&q.front()<i-a+1)
q.pop_front();//把范围外的删去
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <deque>
#include <map>
#include <string>
#include <vector>
//#include <iostream>
using namespace std;
int num[10000100];
int main()
{
long long i,j,k,ans,t,a,n,b;
num[0]=1;
while(~scanf("%lld%lld%lld",&n,&a,&b))
{
for(i=1;i<=n;i++)
{
num[i]=(long long)a*(long long)num[i-1]%(long long)b;
}
ans=1;
deque<int>q;
for(i=1;i<=n;i++)
{
while(!q.empty()&&num[q.back()]>=num[i])
q.pop_back();
q.push_back(i);
while(!q.empty()&&q.front()<i-a+1)
q.pop_front();
ans*=(long long)num[q.front()];
ans%=(long long)b;
}
printf("%lld\n",ans);
}
return 0;
}