题解 CF1311B 【WeirdSort】

ShineEternal

2020-02-26 07:48:26

Solution

[更佳的阅读效果。](https://blog.csdn.net/kkkksc03/article/details/104504289) ## description: - 给定一个长度为 $n$ 的序列 $a_i$。 - 再给定一个长度为 $m$ 的序列 $p_i$。 - 对于每一个 $p_i$,你都可以选择将 $a_{p_i}$ 和 $a_{p_i+1}$ 交换位置,使用次数不限。 - 询问你能否找到一种方案,使得序列满足 $a_1\le a_2\le a_3\le...\le a_n$,输出 `YES` 或 `NO` 即可。 - **多组数据**,数据组数不超过 $100$,$1\le m<n\le 100$,$1\le a_i\le 100$,$1\le p_i< n$。 - translate by @[ShineEternal](https://www.luogu.com.cn/user/45475)。 ## solution: 其实我们可以把 $p_i$ 看成一个个传送带。 首先如果有 $m=n-1$,那么任何情况都能传送,也就是说一定有解。 否则的话,我们可以先把传送带排序。 然后这时候传送带可能会有连成一块一块的。(即连续自然数列) 那么同一块的我们可以随便排序,直接 $\operatorname{sort}$ 即可。 每一块传送带都这么操作,最后对 $a$ 数组进行单调性判断。 ## code: ```cpp #include<cstdio> #include<algorithm> using namespace std; int a[105],p[105]; int main() { int T; scanf("%d",&T); while(T--) { int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); } for(int i=1;i<=m;i++) { scanf("%d",&p[i]); } sort(p+1,p+m+1); if(m==n-1) { printf("YES\n"); continue; } int tmpl=p[1],tmpr=p[1]+1; for(int i=2;i<=m;i++) { if(p[i]>p[i-1]+1) { sort(a+tmpl,a+tmpr+1); tmpl=p[i]; tmpr=p[i]+1; } else { tmpr++; } } sort(a+tmpl,a+tmpr+1); int flag=0; for(int i=2;i<=n;i++) { if(a[i]<a[i-1]) { flag=1; break; } } if(flag==0) { printf("YES\n"); } else { printf("NO\n"); } } return 0; } ```