http://uoj.ac/contest/25/problem/180
从前往后对比串A,B
当$A_i,B_i$不相同时找到$B_i$在A中的位置j
若$min{A_1,A_2,A_3......A_{j-1}}<A_j$说明$A_j$无法交换到位置i,就GG惹
否则把$A_j$设为INF
线段树维护区间取min,单点修改
#include<cstdio> #include<iostream> #include<algorithm> using std::cin; using std::cout; using std::min; using std::max; #define INF 0x7fffffff const int maxn = 100007; int n; inline int read() { int x=0,f=1; char c=getchar(); while(c<'0'||c>'9') { if(c=='-')f=-1;c=getchar() ; } while(c<='9'&&c>='0')x=x*10+c-'0',c=getchar(); return x*f; } int a[maxn],b[maxn]; int pos[maxn]; int minn[(maxn<<2)+3] ; void merge(int rt) { minn[rt]=min(minn[rt<<1],minn[rt<<1|1]); } void build(int l,int r,int rt) { if(l==r) { minn[rt]=a[l];return; } int mid = l+r>>1; build(l,mid,rt<<1); build(mid+1,r,rt<<1|1); merge(rt); } int query(int l,int r,int rt,int tl,int tr) { if(tl<=l&&tr>=r) { return minn[rt]; } int mid=l+r>>1; int ans=INF; if(tl<=mid) ans=min(ans,query(l,mid,rt<<1,tl,tr)); if(tr>mid) ans=min(ans,query(mid+1,r,rt<<1|1,tl,tr)); return ans; } void modify(int l,int r,int rt,int pos) { if(l==r) { minn[rt]=INF;return; } int mid= l+r>>1; if(mid>=pos)modify(l,mid,rt<<1,pos); else if(mid<pos)modify(mid+1,r,rt<<1|1,pos); merge(rt); } int main() { n=read(); for(int i=1;i<=n;++i) a[i]=read(),pos[a[i]]=i; for(int i=1;i<=n;++i) b[i]=read(); build(1,n,1); for(int i=1;i<=n;++i) { //if(a[i]!=b[i]) { int p=pos[b[i]]; int tmp=query(1,n,1,1,p); if(tmp<b[i]) { cout<<"NO"<<std::endl;return 0; } else modify(1,n,1,p); // } } cout<<"YES"<<std::endl; return 0; }