Give you three integers n, A and B.
Then we define S i = A i mod B and T i = Min{ S k | i-A <= k <= i, k >= 1}
Your task is to calculate the product of T i (1 <= i <= n) mod B.
Input
Each line will contain three integers n(1 <= n <= 10
7),A and B(1 <= A, B <= 2
31-1).
Then we define S i = A i mod B and T i = Min{ S k | i-A <= k <= i, k >= 1}
Your task is to calculate the product of T i (1 <= i <= n) mod B.
Process to end of file. Output For each case, output the answer in a single line. Sample Input
1 2 3 2 3 4 3 4 5 4 5 6 5 6 7Sample Output
2 3 4 5 6
题意:
T
i
= Min{ S
k
| i-A <= k <= i, k >= 1} ,Ti是i-A到i这个范围内S的最小值,求(T1*T2*T3.......Tn)%Bd的值。
思路:单调队列可以在o(n)的复杂度内求出区间内的最小值,用单调队列记录区间的最小值,求出答案。
#include<algorithm>
#include<stdio.h>
#include<string.h>
const int M=1e7+10;
using namespace std;
int s[M];
int q_max[M];
int main()
{
int n,a,b;
while(~scanf("%d%d%d",&n,&a,&b))
{
int head_max=0,tail_max=0;
long long pan=1,ans=1;
for(int i=1;i<=n;i++)
{
pan=(pan*a)%b;
s[i]=pan;
while(head_max<tail_max&&s[q_max[tail_max-1]]>=s[i])tail_max--;
q_max[tail_max++]=i;
while(i-a>q_max[head_max])head_max++;
ans=(ans*s[q_max[head_max]])%b;
}
printf("%lld\n",ans);
}
return 0;
}