题意:给你两个长度为 n 的序列 a 和 b , 可以对 a 进行 操作: 选择一段区间[ l, r ] ,使得序列a 在这段区间里 按升序排序。 可以对a 进行任意多次操作,问 a是否有可能变成b序列。

解: 首先,枚举b序列,然后在a中,找这个元素在a出现的位置(如果是第一次出现的,就找第一次出现的那个位置,第二次出现就找第二次出现的) pos ,然后查询 0 ~ pos 的最小值 (线段树),若 最小值是 b对应的那个元素,就满足,否则,就不满足。 然后若满足,需要更新线段树,把查询的元素更新为INF,不然会影响后面查询。

/// 试公式的 勿cheat
#include <iostream>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <map>
#include <stack>
#include <set>
#define LL long long
#define ULL unsigned long long
#define re register
#define rep(i,j,k) for(re int i=j;i<=k;i++)
#define dep(i,j,k) for(re int i=k;i>=j;i--)
#define INF 0x3f3f3f3f
#define mem(i,j) memset(i,j,sizeof(i))
#define make(i,j) make_pair(i,j)
#define pb push_back
using namespace std;
const int N = 3e5 + ;
vector<int>G[N];
int a[N], b, du[N]; ///du 代表这个元素出现的 第几次
int rr[N << ];
void pushdown(int root) {
rr[root] = min(rr[root<<], rr[root<<|]);
return ;
}
void built(int l, int r, int root) {
if(l == r) {
rr[root] = a[l]; return ;
}
int mid = (l + r) >> ;
built(l, mid, root << );
built(mid + , r, root << | );
pushdown(root);
}
void updat(int l, int r, int x, int val, int root) {
if(l == r) {
rr[root] = val; return ;
}
int mid = (l + r) >> ;
if(x <= mid) updat(l, mid, x, val, root << );
else updat(mid + , r, x, val, root << | );
pushdown(root);
}
int query(int l, int r, int x, int y,int root) {
if(x <= l && r <= y) return rr[root];
int mid = (l + r) >> ;
int ans = INF;
if(x <= mid) ans = min(ans, query(l, mid, x, y, root << ));
if(y > mid) ans = min(ans, query(mid + , r, x, y, root << | ));
return ans ;
}
int main() {
int t, n;
scanf("%d", &t);
while(t--) {
scanf("%d", &n);
rep(i, , n) G[i].clear(), du[i] = ;
rep(i, , n) { scanf("%d", &a[i]); G[a[i]].pb(i); }
built(, n, );
//cout << query(1, n, 2, 4, 1) << endl;
int flag = ;
rep(i, , n) {
scanf("%d", &b);
//if(flag) { cout << i - 1 << endl; continue; }
if(du[b] == (int)G[b].size()) { flag = ; continue; } ///b中这个元素的个数比a中的多,那肯定不满足啦,元素都不完全一样。
int pos = G[b][du[b]];
if(pos == ) flag = ;
//if(pos <= i) continue;
int p = query(, n, , pos, );
if(p != b) flag = ;
updat(, n, G[b][du[b]++], INF, );
}
if(flag) puts("NO");
else puts("YES");
}
return ;
}

最新文章

  1. django缓存优化中caches参数如何配置?
  2. iOS之App加急审核详细步骤
  3. 数据库Date类型和JavaDate类型的转换
  4. WebService &ndash; 3.后台调用WebService,根级别上的数据无效
  5. JAVA 注解的几大作用及使用方法详解【转】
  6. 基于clahe的图像去雾
  7. iOS - 表格
  8. stm32 DAC输出音频
  9. 蓝桥杯--算法训练 区间k大数查询
  10. sublime_text 破解
  11. Nlpir Parser敏感词搜索灵玖语义技术应用
  12. c语言中的#ifdef和#ifndef
  13. JDBC数据库连接简介(一)
  14. 四种对话框(dialog)的简单使用方法
  15. Mysql数据库的(行记录)详细操作
  16. spring 对jdbc的简化
  17. 为什么call比apply快
  18. css 相对单位rem详解
  19. jQuery 版本选择与常见插件库总结
  20. redis5.0.4-cluster集群搭建及jedis客户端操作

热门文章

  1. JavaWeb应用系统开发实训任务(一)
  2. js排列组合
  3. Asp.net core Identity + identity server + angular + odata + 权限管理
  4. 高性能MySQL3_笔记0
  5. OAuth授权看这篇就够了
  6. lua与c的交互(运用)
  7. thymeleaf 模板使用 之 前台界面获取后台属性值
  8. java 异常捕捉 ( try catch finally ) 你真的掌握了吗?
  9. 洛谷题解P4314CPU监控--线段树
  10. 用最少的JS代码写出贪吃蛇游戏---迷你版