CF1187D. Subarray Sorting
想要把一个数x换到前面,x一定是小一点的值。由于B串是固定的,A串可调整,我们可以遍历B数组,对于B【i】,找到对于在A数组的位子pos,判断1~pos中,是不是A【pos】最小,如果是最小,说明可以换到最前面,把A【pos】的值变为inf后,继续遍历。
#include <cstdio> #include <vector> #include <cstring> #include <algorithm> #include <iostream> #include <queue> using namespace std; #define pb push_back #define fi first #define se second #define debug(x) cerr<<#x << " := " << x << endl; #define bug cerr<<"-----------------------"<<endl; #define FOR(a, b, c) for(int a = b; a <= c; ++ a) typedef long long ll; typedef long double ld; typedef pair<int, int> pii; typedef pair<ll, ll> pll; const int inf = 0x3f3f3f3f; const int MOD = 1e9+7; /**********showtime************/ const int maxn = 3e5+9; int a[maxn], b[maxn]; queue<int>que[maxn]; int mn[maxn<<2]; void update(int pos, int val, int le, int ri, int rt) { if(le == ri) { mn[rt] = val; return ; } int mid = (le + ri) >> 1; if(mid >= pos) update(pos, val, le, mid, rt<<1); else update(pos, val, mid+1, ri, rt<<1|1); mn[rt] = min(mn[rt<<1], mn[rt<<1|1]); } int query(int L, int R, int le, int ri, int rt) { if(le >= L && ri <= R) { return mn[rt]; } int mid = (le + ri) >> 1; int res = inf; if(mid >= L) res = min(res, query(L,R,le, mid, rt<<1)); if(mid < R) res = min(res, query(L,R,mid+1, ri, rt<<1|1)); return res; } void build(int le, int ri, int rt) { if(le == ri) return ; int mid = (le + ri) >> 1; build(le, mid, rt<<1); build(mid+1, ri, rt<<1|1); } int main(){ int T; scanf("%d", &T); while(T--) { int n; scanf("%d", &n); build(1, n, 1); for(int i=1; i<=n; i++) scanf("%d", &a[i]), que[a[i]].push(i), update(i, a[i], 1, n, 1); for(int i=1; i<=n; i++) scanf("%d", &b[i]); int flag = 1; for(int i=1; i<=n; i++) { if(!que[b[i]].empty()) { int p = que[b[i]].front(); que[b[i]].pop(); if(query(1, p, 1, n, 1) < b[i]) flag = 0; else update(p, inf, 1, n, 1); } else flag = 0; } for(int i=1; i<=n; i++) { while(!que[a[i]].empty()) que[a[i]].pop(); } puts(flag?"YES":"NO"); } return 0; }