每次重新换球改变的是杯子与杯子间的相对位置
因此对于杯子的排列
如
0 1 2 3 4 5 6 7 8 9
为初始状态
调换第3个和第4个
相对来说顺序变为 =( 0 1 2 4 3 5 6 7 8 9 )
以这种串的形式表示原来的第个纸杯移动到了
的位置
即对于目前第三个杯子和第四个杯子换了
状态可叠加
即
( 0 1 2 3 4 5 6 7 8 9 ) + ( 0 1 2 4 3 5 6 7 8 9 ) = ( 0 1 2 4 3 5 6 7 8 9 )
比如
↓初始串---------------------↓相对串--------------------↓结果串
( 0 1 2 4 3 5 6 7 8 9 ) + ( 1 0 2 3 4 5 6 7 8 9 ) = ( 1 0 2 4 3 5 6 7 8 9 )
实质是以初始串为基础情况以相对串为相对位置的得出最终位置
考虑如果初始串第位将会被基于相对串相对的移动到第
位的位置
node add(node x,node y){
node tmp;
for(int i=0;i<=9;++i) tmp.p[y.p[i]]=x.p[i];
return tmp;
}既然可以相加,必然可以相减
↓结果串---------------------↓初始串--------------------↓相对串
( 1 0 2 4 3 5 6 7 8 9) - ( 0 1 2 4 3 5 6 7 8 9 ) = ( 1 0 2 3 4 5 6 7 8 9 )
相减的实质是还原,那么考虑如果结果串的第位与初始串的第
位相等,可得到相对串的第
位是
node sub(node x,node y){
node tmp;
for(int i=0;i<=9;++i)
for(int j=0;j<=9;++j)
if(x.p[i]==y.p[j])
tmp.p[i]=j;
return tmp;
}结果求得就是相对串,贴一下代码
#include<bits/stdc++.h>
#define maxn 100010
using namespace std;
int n,m;
struct node{
int p[10];
}data[maxn];
void clean(node &x){for(int i=0;i<=9;++i) x.p[i]=i;}
node add(node x,node y){
node tmp;
for(int i=0;i<=9;++i) tmp.p[y.p[i]]=x.p[i];
return tmp;
}
node sub(node x,node y){
node tmp;
for(int i=0;i<=9;++i)
for(int j=0;j<=9;++j)
if(x.p[i]==y.p[j])
tmp.p[i]=j;
return tmp;
}
void print(node x){for(int i=0;i<=9;++i) printf("%d ",x.p[i]);putchar('\n');}
int main(){
scanf("%d%d",&n,&m);
clean(data[0]);
for(int i=1;i<=n;++i){
int a,b;
scanf("%d%d",&a,&b);
clean(data[i]); swap(data[i].p[a],data[i].p[b]);
data[i]=add(data[i-1],data[i]);
}
for(int i=1;i<=m;++i){
int l,r;
scanf("%d%d",&l,&r);
print(sub(data[r],data[l-1]));
}
return 0;
}
京公网安备 11010502036488号