【UR #12】实验室外的攻防战(BIT)

时间:2021-01-18 05:20:00

【题目链接】

http://uoj.ac/problem/180

【题意】

给定两个1..n的排列AB,只有当ai<ai+1才能交换ai和ai+1,问是否能够将A转换为B。

【思路】

令a[i]表示i在A中的出现位置,b[i]表示i在B中的出现位置。

若满足i<j,且不存在a[i]<a[j]&&b[i]>a[j]则输出YES,否则输出NO。

用个树状数组维护最大值即可判断。

【证明】

  【UR #12】实验室外的攻防战(BIT)

【代码】

 #include<set>
#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define trav(u,i) for(int i=front[u];i;i=e[i].nxt)
#define FOR(a,b,c) for(int a=(b);a<=(c);a++)
using namespace std; typedef long long ll;
const int N = 2e5+; ll read() {
char c=getchar();
ll f=,x=;
while(!isdigit(c)) {
if(c=='-') f=-; c=getchar();
}
while(isdigit(c))
x=x*+c-'',c=getchar();
return x*f;
} int a[N],b[N],X[N];
int n; int C[N];
void upd(int x,int v)
{
for(;x<=n;x+=x&-x)
C[x]=max(C[x],v);
}
int query(int x)
{
int res=;
for(;x;x-=x&-x)
res=max(res,C[x]);
return res;
} int main()
{
n=read();
FOR(i,,n) {
X[i]=read();
a[X[i]]=i;
}
FOR(i,,n) {
X[i]=read();
b[X[i]]=i;
}
FOR(i,,n) {
int x=query(a[i]);
if(b[i]<x) { puts("NO"); return ; }
upd(a[i],b[i]);
}
puts("YES");
return ;
}

P.S. UOJ 棒棒哒~