题意:给定两个数组 a,b;现在需要构造a数组 n+1~ 2n 的项;
要求: 在 bk <= j < i 的前提下, ai =Max { aj - j } ;
现在求出Σ ai , i from n+1 to 2n 的最大值;
思路: 贪心; 怎么贪心呢? 不妨这么考虑,由于选的要减去 i ;所以 bk 肯定尽量小,那么我们将b数组排序,每次取前面的而且没有取过的即可,同时维护一下 i ~ end 的最大值即可
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<string>
#include<bitset>
#include<ctime>
#include<deque>
#include<stack>
#include<functional>
#include<sstream>
using namespace std;
typedef long long ll;
#define maxn 500005
const int mod=1e9+7;
#define inf 0x3f3f3f3f
#define ms(x) memset(x,0,sizeof(x))
void exgcd(ll a,ll b,ll &d,ll &x,ll &y)
{
if(b==0){
x=1;y=0;d=a;
}
else {
exgcd(b,a%b,d,y,x);
y-=x*(a/b);
}
}
int a[maxn],b[maxn];
int Max[maxn];
int main()
{
ios::sync_with_stdio(false);
int n;
while(cin>>n){
int i,j;
ms(Max);
for(i=1;i<=n;i++){
cin>>a[i];a[i]-=i;
}
for(i=1;i<=n;i++){
cin>>b[i];
}
sort(b+1,b+1+n);
Max[n]=a[n];
for(i=n;i>=2;i--){
Max[i-1]=max(Max[i],a[i-1]);
}
int tt=n+1;
int sum=0;
for(i=1;i<=n;i++){
sum+=Max[b[i]];
a[tt]=Max[b[i]]-tt;
Max[tt]=a[tt];
for(j=tt-1;j>=1;j--){
// Max[j]=max(Max[j],Max[tt]);
if(Max[j]<Max[tt]){
Max[j]=Max[tt];
}
else break;
}
tt++;
sum%=mod;
}
cout<<sum<<endl;
}
}