每次重新换球改变的是杯子与杯子间的相对位置
因此对于杯子的排列
如
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; }