【题目链接】
【题意】
给定两个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。
用个树状数组维护最大值即可判断。
【证明】
【代码】
1 #include<set> 2 #include<cmath> 3 #include<queue> 4 #include<vector> 5 #include<cstdio> 6 #include<cstring> 7 #include<iostream> 8 #include<algorithm> 9 #define trav(u,i) for(int i=front[u];i;i=e[i].nxt) 10 #define FOR(a,b,c) for(int a=(b);a<=(c);a++) 11 using namespace std; 12 13 typedef long long ll; 14 const int N = 2e5+10; 15 16 ll read() { 17 char c=getchar(); 18 ll f=1,x=0; 19 while(!isdigit(c)) { 20 if(c==‘-‘) f=-1; c=getchar(); 21 } 22 while(isdigit(c)) 23 x=x*10+c-‘0‘,c=getchar(); 24 return x*f; 25 } 26 27 int a[N],b[N],X[N]; 28 int n; 29 30 int C[N]; 31 void upd(int x,int v) 32 { 33 for(;x<=n;x+=x&-x) 34 C[x]=max(C[x],v); 35 } 36 int query(int x) 37 { 38 int res=0; 39 for(;x;x-=x&-x) 40 res=max(res,C[x]); 41 return res; 42 } 43 44 int main() 45 { 46 n=read(); 47 FOR(i,1,n) { 48 X[i]=read(); 49 a[X[i]]=i; 50 } 51 FOR(i,1,n) { 52 X[i]=read(); 53 b[X[i]]=i; 54 } 55 FOR(i,1,n) { 56 int x=query(a[i]); 57 if(b[i]<x) { puts("NO"); return 0; } 58 upd(a[i],b[i]); 59 } 60 puts("YES"); 61 return 0; 62 }
P.S. UOJ 棒棒哒~
时间: 2024-10-12 21:18:30