UOJ 180【UR #12】实验室外的攻防战

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;
}
原文地址:https://www.cnblogs.com/sssy/p/8322091.html