E. Bombs
You are given a permutation, p1,p2,…,pn.
Imagine that some positions of the permutation contain bombs, such that there exists at least one position without a bomb.
For some fixed configuration of bombs, consider the following process. Initially, there is an empty set, A.
For each i from 1 to n:
- Add pi to A.
- If the i-th position contains a bomb, remove the largest element in A.
After the process is completed, A will be non-empty. The cost of the configuration of bombs equals the largest element in A.
You are given another permutation, q1,q2,…,qn.
For each 1≤i≤n, find the cost of a configuration of bombs such that there exists a bomb in positions q1,q2,…,qi−1.
For example, for i=1, you need to find the cost of a configuration without bombs, and for i=n, you need to find the cost of a configuration with bombs in positions q1,q2,…,qn−1.
Input
The first line contains a single integer, n (2≤n≤300000).
The second line contains n distinct integers p1,p2,…,pn (1≤pi≤n).
The third line contains n distinct integers q1,q2,…,qn (1≤qi≤n).
Output
Print n space-separated integers, such that the i-th of them equals the cost of a configuration of bombs in positions q1,q2,…,qi−1.
Examples
input
3
3 2 1
1 2 3
output
3 2 1
input
6
2 3 6 1 5 4
5 2 1 4 6 3
output
6 5 5 5 4 1
解法:
因为答案是非递增的,因此可以把问题转化为判断答案是否为某个数x,不断检查是否合法
假设答案为x,那么序列中每个至少存在一个>=x的数未被炸掉
某个位置需要被炸掉,那么这个位置开始的右边需要有一个炸弹
假设从右边起第k个>=x的位置为pos,那么pos位置向右至少要有k个炸掉
用线段树维护序列b,b(i)表示i位置向右的>=x的数的数量减去炸弹的数量,
如果所有的b(i)<=0,表明>=x的数都被炸没了,那么令x–继续判断直到当存在b(i)>0时x就是当前答案
需要用到区间加法和区间最值。
从判断x转化为到判断x-1的过程中很好维护,因为>=x的一定是>=x-1的。
code:
#include<bits/stdc++.h>
using namespace std;
const int maxm=3e5+5;
int p[maxm],q[maxm],n;
int pos[maxm];
struct ST{
int lz[maxm<<2];
int a[maxm<<2];
void pushup(int node){
a[node]=max(a[node*2],a[node*2+1]);
}
void pushdown(int node){
if(lz[node]){
lz[node*2]+=lz[node];
lz[node*2+1]+=lz[node];
a[node*2]+=lz[node];
a[node*2+1]+=lz[node];
lz[node]=0;
}
}
void update(int st,int ed,int val,int l,int r,int node){
if(st<=l&&ed>=r){
a[node]+=val;
lz[node]+=val;
return ;
}
pushdown(node);
int mid=(l+r)/2;
if(st<=mid)update(st,ed,val,l,mid,node*2);
if(ed>mid)update(st,ed,val,mid+1,r,node*2+1);
pushup(node);
}
int ask(int st,int ed,int l,int r,int node){
if(st<=l&&ed>=r)return a[node];
pushdown(node);
int mid=(l+r)/2;
int ans=-1e9;
if(st<=mid)ans=max(ans,ask(st,ed,l,mid,node*2));
if(ed>mid)ans=max(ans,ask(st,ed,mid+1,r,node*2+1));
return ans;
}
}T;
signed main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&p[i]),pos[p[i]]=i;
for(int i=1;i<=n;i++)scanf("%d",&q[i]);
int x=n;
T.update(1,pos[n],1,1,n,1);
for(int i=1;i<=n;i++){
printf("%d ",x);
T.update(1,q[i],-1,1,n,1);
while(x>=1&&T.ask(1,n,1,n,1)<=0){
x--;
T.update(1,pos[x],1,1,n,1);
}
}
return 0;
}