题目来源:https://nanti.jisuanke.com/t/40255
先了解题目意思进行欧拉降幂把价值算出来,再进行dp计算。
注意dp数组,题目卡内存,所以必须得用滚动数组的形式去计算,不然就会RE。
注意MOD是指数形式才能使用,所以最外层计算的时候还是得用正常的快速幂。
之后进行dp,大的话,由于a,b序列的相对顺序是不会改变的,所以设置一个dp[2][i][j],dp[0/1][i][j]表示a数组的前i个,b数组的前j个的MAX,0或1表示以b数组的结尾或为a数组的结尾,以n^2形式去转移。
然后改为滚动数组的形式去计算,只需要保存上一个的值就ok了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<vector>
#include<algorithm>
#include<map>
#include<queue>
#define MAX_len 50100*4
using namespace std;
typedef long long ll;
const ll p=1e5+3;
const ll MAX=1e5+10;
ll aa[5010],bb[5010];
ll phi[MAX],dp[2][2][5010];
ll MOD(ll n,ll mod)
{
return n<mod?n:(n%mod+mod);
}
void Euler()
{
phi[1]=1;
for(ll i=2;i<MAX;i++)
phi[i]=i;
for(ll i=2;i<MAX;i++)
if(phi[i]==i)
for(ll j=i;j<MAX;j+=i)
phi[j]=phi[j]/i*(i-1);
}
ll quickpow(ll a,ll n,ll mod)
{
ll res=1;
while(n)
{
if(n&1)
{
res=MOD(a*res,mod);
}
n>>=1;
a=MOD(a*a,mod);
}
return res;
}
ll fastpow(ll a,ll n,ll mod)
{
ll res=1;
while(n)
{
if(n&1)
res=(res*a)%mod;
n/=2;
a=(a*a)%mod;
}
return res;
}
ll solve(ll a,ll b,ll mod)
{
if(b==1||mod==1)
return MOD(a,mod);
{
return quickpow(a,solve(a,b-1,phi[mod]),mod);
}
}
int main()
{
Euler();
int a,b,i,j,n;
scanf("%d %d",&a,&b);
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%d",&aa[i]);
if(a==1)
{
aa[i]=1;
continue;
}
else
{
aa[i]=fastpow(a,solve(b,aa[i],phi[p]),p);
}
}
for(i=1;i<=n;i++)
{
scanf("%d",&bb[i]);
if(a==1)
{
bb[i]=1;
continue;
}
else
{
bb[i]=fastpow(a,solve(b,bb[i],phi[p]),p);
}
}
// for(i=1;i<=n;i++)
// {
// printf("%lld %lld\n",aa[i],bb[i]);
// }
for(i=1;i<=n;i++)//a数组用1表示结尾,b数组用0表示结尾。之后分6种情况去判断就行了
{
for(j=1;j<=n;j++)
{
dp[0][i&1][j]=dp[1][i&1][j]=0;
dp[0][i&1][j]=dp[1][i&1][j]=0;
if(bb[j]==bb[j-1])
{
dp[0][i&1][j]=max(dp[0][i&1][j],dp[0][i&1][(j-1)]+bb[j]);
}
else
{
dp[0][i&1][j]=max(dp[0][i&1][j],dp[0][i&1][(j-1)]);
}
if(aa[i]==aa[i-1])
{
dp[1][i&1][j]=max(dp[1][i&1][j],dp[1][(i-1)&1][j]+aa[i]);
}
else
{
dp[1][i&1][j]=max(dp[1][i&1][j],dp[1][(i-1)&1][j]);
}
if(bb[j]==aa[i])
{
dp[0][i&1][j]=max(dp[0][i&1][j],dp[1][i&1][(j-1)]+bb[j]);
dp[1][i&1][j]=max(dp[1][i&1][j],dp[0][(i-1)&1][j]+aa[i]);
}
else
{
dp[0][i&1][j]=max(dp[0][i&1][j],dp[1][i&1][(j-1)]);
dp[1][i&1][j]=max(dp[1][i&1][j],dp[0][(i-1)&1][j]);
}
}
}
printf("%lld",max(dp[0][n&1][n],dp[1][n&1][n]));
return 0;
}