Description
在2050年机器人战争爆发,聪明的机器猫为了帮助大雄打赢这场战 争,从自己口袋里掏出了机器人战棋,每一个战棋都可以成为一名战士,哆啦A梦决定给他们整整队,哆啦A梦发现第 i 个位置的战士编号为 Ai(显然 A 是一个排列)。经过计算,哆啦A梦发现,让第 i 个位置的战士编号为 Bi 时,他的军队可以发挥出最大的战斗力(保证 B 也是一个排列)。
哆啦A梦可以发出指令来改变战士们的排列顺序,每一次,他都会报出一个整数 i(1≤i<n)。如果排在第 i 个位置的战士编号大于第 i+1 个位置的战士,那么这两个战士会交换顺序,否则这一个命令将会被忽略。
现在哆啦A梦希望他的军队能够发挥出最强大的战斗力,于是他想要知道是否存在一种指令序列,使得战士们可以按照排列 B 的方式排列。
但是因为战士数目实在是太多,哆啦A梦一时间也没有看出答案。于是他用时间机器带来了你——21世纪最著名的民间科学家来帮他计算这个问题的答案。
哆啦A梦可以发出指令来改变战士们的排列顺序,每一次,他都会报出一个整数 i(1≤i<n)。如果排在第 i 个位置的战士编号大于第 i+1 个位置的战士,那么这两个战士会交换顺序,否则这一个命令将会被忽略。
现在哆啦A梦希望他的军队能够发挥出最强大的战斗力,于是他想要知道是否存在一种指令序列,使得战士们可以按照排列 B 的方式排列。
但是因为战士数目实在是太多,哆啦A梦一时间也没有看出答案。于是他用时间机器带来了你——21世纪最著名的民间科学家来帮他计算这个问题的答案。
Input
输入数据第一行包含一个正整数 n(n<=100000)。
接下来两行每行 n 个正整数,分别描述排列 A和排列 B。
接下来两行每行 n 个正整数,分别描述排列 A和排列 B。
Output
对于每组数据,如果存在这样的指令序列,输出“YES”,否则输出“NO”(引号不输出,请注意大小写)。
Sample Input
3 2 3 1 2 1 3 3 2 1 3 3 1 2
Sample Output
YES NO
思路:这道题是山科第三届校赛的H题,我们队过的最后一道题,由于太弱,想了大概一个小时左右才初步有了思路
就是先建一棵max的线段树,数组a和b分别记录交换之前和交换之后数值的下标
然后从大到小循环,每次判断该数值是否向右移动(或者不移动),如果成立就询问线段树初始位置在该元素右边的
值移动后所在的最左端的位置。当前数值移动后的位置必须小于查询的结果。
然后每个值都更新线段树,将初始位置的值更新为交换之后的位置。
然后同理从小到大循环,每次判断向左移动,询问最右端的位置就好了
/* *********************************************** Author :devil Created Time :2016/4/26 13:11:52 ************************************************ */ #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <cmath> #include <stdlib.h> using namespace std; const int N=100005; int n,a[N],b[N],tree[N<<2]; void build1(int node,int l,int r) { if(l==r) { tree[node]=N; return ; } int m=(l+r)>>1; build1(node<<1,l,m); build1(node<<1|1,m+1,r); tree[node]=min(tree[node<<1],tree[node<<1|1]); } void update1(int node,int l,int r,int p) { if(l==r) { tree[node]=b[p]; return ; } int m=(l+r)>>1; if(a[p]<=m) update1(node<<1,l,m,p); else update1(node<<1|1,m+1,r,p); tree[node]=min(tree[node<<1],tree[node<<1|1]); } int query1(int node,int l,int r,int p) { if(l>=p) return tree[node]; int m=(l+r)>>1,ans; ans=query1(node<<1|1,m+1,r,p); if(p<=m) ans=min(ans,query1(node<<1,l,m,p)); return ans; } void build2(int node,int l,int r) { if(l==r) { tree[node]=0; return ; } int m=(l+r)>>1; build2(node<<1,l,m); build2(node<<1|1,m+1,r); tree[node]=max(tree[node<<1],tree[node<<1|1]); } void update2(int node,int l,int r,int p) { if(l==r) { tree[node]=b[p]; return ; } int m=(l+r)>>1; if(a[p]<=m) update2(node<<1,l,m,p); else update2(node<<1|1,m+1,r,p); tree[node]=max(tree[node<<1],tree[node<<1|1]); } int query2(int node,int l,int r,int p) { if(r<=p) return tree[node]; int m=(l+r)>>1,ans; ans=query2(node<<1,l,m,p); if(p>m) ans=max(ans,query2(node<<1|1,m+1,r,p)); return ans; } int main() { //freopen("in.txt","r",stdin); while(~scanf("%d",&n)) { int x,flag=1; for(int i=1; i<=n; i++) { scanf("%d",&x); a[x]=i; } for(int i=1; i<=n; i++) { scanf("%d",&x); b[x]=i; } build1(1,1,n); for(int i=n; i>0; i--) { if(a[i]<=b[i]&&b[i]>query1(1,1,n,a[i])) { flag=0; break; } update1(1,1,n,i); } if(!flag) { printf("NO "); continue; } build2(1,1,n); for(int i=1; i<=n; i++) { if(a[i]>=b[i]&&b[i]<query2(1,1,n,a[i])) { flag=0; break; } update2(1,1,n,i); } if(!flag) printf("NO "); else printf("YES "); } return 0; }