题解 CF1630D【Flipping Range】
本篇是 CF1630D 的题解,请管理员暂且从 CF1603D 的题解处撤下本篇,谢谢!
这题初看起来也许有些无从下手,我们先来分析一些简单的情况。假若存在某个
我们来考虑,如果对一组
从这里实际上已经可以发现此题和辗转相除法的关系了。利用两个权值为
接下来的问题并不困难。观察到每次操作一定恰好反转了下标模
#include<cstdio>
#include<algorithm>
using namespace std;
int gcd(int x,int y){return y?gcd(y,x%y):x;}
long long a[2000000];
long long dp[2000000][2];
int main()
{
int T=0;scanf("%d",&T);
while(T--)
{
int n=0,m=0;scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
int d=0;for(int i=1,b=0;i<=m;i++){scanf("%d",&b);d=gcd(b,d);}
for(int i=n;i>=1;i--)
{
if(i+d>n)dp[i][0]=a[i],dp[i][1]=-a[i];
else dp[i][0]=max(dp[i+d][0]+a[i],dp[i+d][1]-a[i]),
dp[i][1]=max(dp[i+d][1]+a[i],dp[i+d][0]-a[i]);
}
long long sum1=0,sum2=0;for(int i=1;i<=d;i++)sum1+=dp[i][0],sum2+=dp[i][1];
printf("%lld\n",max(sum1,sum2));
}
}