题意:
把b数组中 b[i]~n放到a[i+n]的位置
思路: 区间最值查
#include <stdio.h>
#include <algorithm>
#include <cstring>
#include <iostream>
using namespace std;
const int maxn= 250005*2;
const int inf=0x3f3f3f3f;
int a[maxn];
int b[maxn];
const int mod=1000000007;
struct node
{
int left,right,maxx ;
}tree[4*maxn];
int n,q;
void Build(int i,int left,int right)
{
tree[i].left=left,tree[i].right=right;
if(left==right)
{
tree[i].maxx=-inf;
if(left<=n)
tree[i].maxx=a[ tree[i].left ]-left;
return ;
}
int mid=(tree[i].left+tree[i].right)>>1;
Build(i<<1,left,mid);
Build(i<<1|1,mid+1,right);
tree[i].maxx=max(tree[i<<1].maxx,tree[i<<1|1].maxx);
return ;
}
int ansmax ;
void query(int i,int left,int right)
{
if(tree[i].right==right&&tree[i].left==left)
{
ansmax=max(ansmax,tree[i].maxx);
return ;
}
int mid=(tree[i].left+tree[i].right)>>1;
if(left>mid)
{
query(i<<1|1,left,right);
}
else if(right<=mid)
{
query(i<<1,left,right);
}
else
{
query(i<<1,left,mid);
query(i<<1|1,mid+1,right);
}
return ;
}
void update(int i,int pos,int num)
{
if(tree[i].left==pos&&tree[i].right==pos)
{
tree[i].maxx=num-pos;
return ;
}
int mid=(tree[i].left+tree[i].right)>>1;
if(pos<=mid)
update(i<<1,pos,num);
else
update(i<<1|1,pos,num);
tree[i].maxx=max(tree[i<<1].maxx,tree[i<<1|1].maxx);
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
memset(tree,0,sizeof(tree));
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=n;i++)
scanf("%d",&b[i]);
Build(1,1,n*2);
sort(b+1,b+1+n);
long long res=0;
for(int i=1;i<=n;i++)
{
int l,r;
l=b[i],r=n+i-1;
ansmax=0;
query(1,l,r);
res+=ansmax;
res%=mod;
update(1,i+n,ansmax);
// printf("%d\n",ansmax);
}
printf("%lld\n",res);
}
}