[日常训练]变戏法
Posted Aireen Ye
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[日常训练]变戏法相关的知识,希望对你有一定的参考价值。
Description
一开始有$n$个只有颜色不同的小球。定义使用一次膜法的效果是重新排列第$l_i$个到第$r_i$个小球。给定了$n$个小球的初始状态和最终状态,以及$m$次膜法的范围$l_i,r_i$。判断是否可以从初始状态转移到最终状态。
Input
第一行有一个整数$t$表示数据组数。
每组数据中,
第一行两个整数$n,m$,表示总共有$n$个小球,$m$次操作。
第二行$n$个整数$a_i$,表示初始状态。
第三行$n$个整数$b_i$,表示最终状态。
接下来$m$行,每行两个整数$l_i,r_i$。
Output
输出共$t$行。对于每组数据,如果合法,输出"$TAK$",否则输出"$NIE$"。
Sample Input
3
10 3
1 2 3 4 5 6 7 8 9 10
2 1 3 6 4 5 9 8 7 10
4 8
1 3
5 9
10 3
1 2 3 4 5 6 7 8 9 10
2 1 3 6 10 4 5 9 8 7
4 8
1 3
5 9
10 3
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 9
4 8
1 3
5 9
Sample Output
TAK
NIE
NIE
HINT
$1\;\leq\;t\;\leq\;10,1\;\leq\;n,m,a_i,b_i\;\leq\;1000$.
Solution
对于颜色相同的小球,如果可行,一定存在一种不改变它们相对顺序的方法。所以我们可以将所有小球一一对应。然后将最终状态的小球从$1$到$n$标号,然后每次操作相当于区间排序。最后判断是否相等即可。
#include<cmath> #include<ctime> #include<queue> #include<stack> #include<cstdio> #include<vector> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> #define N 1005 using namespace std; int a[N],c[N][N],t[N],n,m,ti; bool flag; inline int read(){ int ret=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)){ ret=(ret<<1)+(ret<<3)+c-‘0‘; c=getchar(); } return ret; } inline void Aireen(){ ti=read(); while(ti--){ n=read();m=read(); memset(t,0,sizeof(t)); for(int i=1;i<=n;++i) a[i]=read(); for(int i=1,k;i<=n;++i){ k=read();c[k][++t[k]]=i; } for(int i=n,k;i;--i){ k=a[i];a[i]=c[k][t[k]--]; } for(int i=1,l,r;i<=m;++i){ l=read();r=read(); sort(a+l,a+1+r); } flag=true; for(int i=1;i<=n;++i) if(a[i]!=a[i-1]+1){ flag=false;break; } if(flag) puts("TAK"); else puts("NIE"); } } int main(){ freopen("mogic.in","r",stdin); freopen("mogic.out","w",stdout); Aireen(); fclose(stdin); fclose(stdout); return 0; }
以上是关于[日常训练]变戏法的主要内容,如果未能解决你的问题,请参考以下文章
地铁译:Spark for python developers ---Spark的数据戏法