rt,这份代码是 m2 的,题目中说 m≤5×105,应该无法通过才对,但它却AC了
#include<bits/stdc++.h>
using namespace std;
const int N=5e5+5;
typedef long long ll;
int n,q;
ll a[N],b[N],c[N],v[N],FC[N],FB[N];
ll m,p[N],DP0[N],mindp=0,mindpid=0;
int main()
{
//freopen("reserve7.in","r",stdin);
//freopen("reserve7.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
for(int i=1;i<=n;i++)
scanf("%lld",&b[i]);
for(int i=1;i<=n;i++)
scanf("%lld",&c[i]);
scanf("%d",&q);
memset(DP0,0x3f,sizeof(DP0));
for(int i=1;i<=n;i++)
{
FC[i]=FC[i-1]+c[i];
FB[i]=FB[i-1]+b[i];
}
if(FC[n]==0)
{
DP0[0]=0;
for(int i=1;i<=n;i++)
{
DP0[i]=min(a[i],DP0[i-1]+b[i]);
}
}
else
{
DP0[0]=0;
for(int i=1;i<=n;i++)
{
DP0[i]=min(a[i],DP0[i-1]+b[i]);
}
}
while(q--)
{
//memset(ans,0,sizeof(ans));
scanf("%lld",&m);
ll ans1=LONG_MAX,ans2=0;
for(int i=1;i<=m;i++)
{
scanf("%lld",&p[i]);
}
if(m==0)
{
printf("%lld\n",DP0[n]);
continue;
}
else if(m==1)
{
ans1=DP0[n]+c[p[m]];
ans2=DP0[p[m]-1]+FB[n]-FB[p[m]];
ans1=min(ans1,ans2);
printf("%lld\n",ans1);
continue;
}
else if(FC[n]==0)
{
/*int max0=n,i=m;
while(p[m]==max0) {max0--;m--;}*/
ans1=DP0[n]+c[p[m]];
for(int i=1;i<=m;i++)
{
ans2=DP0[p[i]-1]+FB[n]-FB[p[i]];
ans1=min(ans1,ans2);
}
printf("%lld\n",ans1);
continue;
}
for(int i=1;i<=m;i++)
{
//将1~p[i]-1位置 设为0
int le=1,ri=p[i]-1;
ans2=DP0[ri];
//遍历左边为0的点,单独设1,第i点不用设置
for(int j=1;j<i;j++)
{
ans2+=c[p[j]];
}
//遍历右边为1的点,单独设0
for(int j=i;j<m;j++)
{
ans2+=FB[p[j+1]-1]-FB[p[j]];
}
//最后到n的点,单独设0
ans2+=FB[n]-FB[p[m]];
ans1=min(ans1,ans2);
}
///全部设0,再单独设置1
ans2=DP0[n];
for(int i=1;i<=m;i++)
ans2+=c[p[i]];
ans1=min(ans1,ans2);
printf("%lld\n",ans1);
}
return 0;
}