http://codeforces.com/contest/1311/problem/B
題目大意:
給出數組a,p
對於每一個 pi,你都可以選擇將api 和api+1 交換位置,使用次數不限
詢問你能否找到一種方案,使得序列滿足 a1≤a2≤a3≤...≤an,輸出 YES
或 NO
即可。
思路:
把 pi 看成一個個傳送帶。
首先如果有 m=n−1那麼任何情況都能傳送,也就是說一定有解。
否則的話,我們可以先把傳送帶排序。
然後這時候傳送帶可能會有連成一塊一塊的。(即連續自然數列)
那麼同一塊的我們可以隨便排序,直接 sort 即可。
每一塊傳送帶都這麼操作,最後對 a 數組進行單調性判斷
#include <iostream>
#include <algorithm>
#include <cmath>
#include <ctype.h>
#include <cstring>
#include <cstdio>
#include <set>
#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>
#include<iomanip>
#define SIS std::ios::sync_with_stdio(false)
#define ll long long
#define INF 0x3f3f3f3f
const int mod = 1e9 + 7;
const double esp = 1e-5;
const double PI = 3.141592653589793238462643383279;
using namespace std;
const int N = 1e7 + 5;
const int maxn = 1 << 20;
ll powmod(ll a, ll b) { ll res = 1; a %= mod; while (b >= 0); for (; b; b >>= 1) { if (b & 1)res = res * a % mod; a = a * a % mod; }return res; }
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
/*************************************************************/
int a[N], p[N];
int main() {
int t;
cin >> t;
while (t--) {
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; i++)
cin >> a[i];
for (int i = 1; i <= m; i++)
cin >> p[i];
sort(p + 1, p + 1 + m);
if (n == m - 1) {
cout << "YES" << endl;
continue;
}
int l = p[1];
int r = p[1] + 1;
for (int i = 2; i <= m; i++) {
if (p[i] > p[i - 1] + 1) {
sort(a + l, a + r + 1);
l = p[i];
r = p[i] + 1;
}
else {
r++;
}
}
sort(a + l, a + r+1);
int sign = 0;
for (int i = 2; i <= n; i++) {
if (a[i] < a[i - 1]) {
sign = 1;
break;
}
}
if (sign)
cout << "NO" << endl;
else
cout << "YES" << endl;
}
return 0;
}