线段树模板(区间最值)
using namespace std;
typedef long long LL;
const int N = 2e5;
const int mol = 1e9 + 7;
int a[N * 2] , b[N * 2];
int l , r , setv[N * 4 * 2 + 10] , v , _sum , p;
void update(int o , int L , int R) o是节点
{
int M = (L + R) >> 1;
if(L == R) setv[o] = v;
else {
if(p <= M) update(o * 2 , L , M);
else update(o * 2 + 1 , M + 1 , R);
setv[o] = max(setv[o * 2] , setv[o * 2 + 1]);
}
}
void query(int o , int L , int R)
{
int M = (L + R) >> 1;
if(l <= L && r >= R)
_sum = max(_sum , setv[o]);
else{
if(l <= M) query(o * 2 , L , M);
if(r > M) query(o * 2 + 1 , M + 1 , R);
}
}
int main()
{
int n;
while(~scanf("%d",&n)){
for(int i = 1 ; i <= n ; i++) scanf("%d",&a[i]);
for(int i = 1 ; i <= n ; i++) scanf("%d",&b[i]);
sort(b + 1 , b + 1 + n);
for(int i = 1 ; i <= n ; i++){
p = i;
v = a[i] - i;
update(1 , 1 , 2 * n);
}
LL sum = 0;
for(int i = n + 1 ; i <= 2 * n ; i++){
l = b[i - n] , r = i - 1;
_sum = 0;
query(1 , 1 , 2 * n);
sum = (sum + _sum) % mol;
p = i;
v = _sum - i;
update(1 , 1 , 2 * n);
}
printf("%d\n",sum);
}
return 0;
}