The 2019 ICPC China Nanchang National Invitational and Inter
发布时间:2020-12-16 09:12:47 所属栏目:百科 来源:网络整理
导读:题目链接:https://nanti.jisuanke.com/t/40255 中文题面: ? 解题思路:先用欧拉降幂求出A,B两个序列,定义dp【0】【i】【j】为取A的前i个元素,B的前j个元素,且C的最后一个元素为B【j】,同理dp【1】【i】【j】为取A的前i个元素,B的前j个元素,且C的最
题目链接:https://nanti.jisuanke.com/t/40255 中文题面: ? 解题思路:先用欧拉降幂求出A,B两个序列,定义dp【0】【i】【j】为取A的前i个元素,B的前j个元素,且C的最后一个元素为B【j】,同理dp【1】【i】【j】为取A的前i个元素,B的前j个元素,且C的最后一个元素为A【i】,那么就很容易得到状态转移方程。那么最后答案即为max(dp【0】【n】【n】,dp【1】【n】【n】)。还有值得注意的是:该题需要使用滚动数组,不然会超内存。 在此贴两个关于欧拉降幂的链接吧:https://blog.csdn.net/qq_37632935/article/details/81264965 https://blog.csdn.net/u013534123/article/details/78912721 #include<bits/stdc++.h> using namespace std; typedef long long ll; const ll mod=100003; const int maxn=5003; int v1[maxn],v2[maxn]; ll a1[maxn],b1[maxn]; ll dp[2][3][maxn]; ll Mod(ll n,ll m){ return n<m?n:(n%m+m); } ll ph(ll n){ ll ans=n; ll res=n; for(int i=2;i*i<=res;i++){ if(n%i==0){ ans=ans/i*(i-1); while(n%i==0){ n/=i; } } } if(n>1)ans=ans/n*(n-1); return ans; } ll qpow(ll n,ll m,ll mo){ // cout<<"YESn"; ll ans=1; while(m){ if(m&1)ans=ans*n%mo; m/=2; n=n*n%mo; } return ans; } ll solve(int num,ll mo,ll tt){ if(num==1||mo==1)return Mod(tt,mo); return qpow(tt,solve(num-1,ph(mo),tt)+ph(mo),mo); } int main(){ ll a,b; scanf("%lld%lld",&a,&b); int n; scanf("%d",&n); for(int i=0;i<n;i++){ scanf("%d",&v1[i]); } for(int i=0;i<n;i++){ scanf("%d",&v2[i]); } for(int i=0;i<n;i++){ a1[i+1]=qpow(a,solve(v1[i],mod-1,b)+mod-1,mod); } for(int i=0;i<n;i++){ b1[i+1]=qpow(a,solve(v2[i],mod); } for(int i=1;i<=n;i++){//1 for(int j=1;j<=n;j++){//0 dp[0][i&1][j]=dp[1][i&1][j]=0; if(b1[j]==a1[i]){ dp[0][i&1][j]=max(dp[0][i&1][j],dp[1][i&1][(j-1)]+b1[j]); dp[1][i&1][j]=max(dp[1][i&1][j],dp[0][(i-1)&1][j]+a1[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]); } if(b1[j]==b1[j-1]){ dp[0][i&1][j]=max(dp[0][i&1][j],dp[0][i&1][(j-1)]+b1[j]); } else{ dp[0][i&1][j]=max(dp[0][i&1][j],dp[0][i&1][(j-1)]); } if(a1[i]==a1[i-1]){ dp[1][i&1][j]=max(dp[1][i&1][j],dp[1][(i-1)&1][j]+a1[i]); } else{ dp[1][i&1][j]=max(dp[1][i&1][j],dp[1][(i-1)&1][j]); } // cout<<i<<" "<<j<<" "<<dp[0][i&1][j]<<" "<<dp[1][i&1][j]<<endl; } } cout<<max(dp[0][n&1][n],dp[1][n&1][n])<<endl; return 0; } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容
- c# – 从IntPtr(16位)数组复制到托管的ushort
- cocos2dx-3.0以上系列如何在android平台上配置
- 利用cocos2dx 3.2开发消灭星星(十)为游戏添加音效(项目源
- 【cocos2d-x 3.x 学习与应用总结】2: 在cocos2d-x中使用ccb
- 常见Sqlite管理工具
- PostgreSQL物理备份与恢复
- React-native Android Java Module如何暴露自己的方法给js
- 我可以使用Flutter在Android Studio中开发IOS吗?
- C# 识别url是否是网络路径
- c# – 如何使用Aero Glass,Jump List等Windows 7 API