【[AHOI2005]洗牌 题解

一道好题。

首先是数据范围。


0<N≤10^10 ,0 ≤M≤10^10,且N为偶数


这是这道题的坑点,也是痛点。

10^10表示这这道题必有规律。

那么,first step,我们先探索规律。

以下表格中,前n列表示纸牌变化,最后一列表示1的位置。


1 2 1

2 1 2

1 2 1


1 2 3 4 1

3 1 4 2 2

4 3 2 1 4

2 4 1 3 3

1 2 3 4 1


1 2 3 4 5 6 1

4 1 5 2 6 3 2

2 4 6 1 3 5 4

1 2 3 4 5 6 3


那么,从一的位置,我们可以看出, 对于当前位置n,纸牌数量a,来说:

若n<a/2 n=n*n;

若n>a/2 n=(n-a/2)*2-1;


附上代码:

 while(k!=a/2+1)
{
  if(k<=a/2)
  {
      k=k*2;
      o++;
      continue; 
  }
  if(k>a/2)
  {
      k=(k-a/2)*2-1;
      o++;
      continue; 
  }
}

有了这个以后,我们可以相当程度上简化此问题。

那么第二步,还原。

还是看上表中一的位置

1->2->1

1->2->4->3->1

1->2->4->1

规律如下

如果n%2==0 n=n/2;

else n=(n+1)/2+a/2;

附上代码:


for(int i=1;i<=b;i++)
{
    if(c%2==1)
    {
        c=(c+1)/2+a/2;
        continue; 
    }
    if(c%2==0)
    {
        c=c/2;
        continue;
    }
}

猜你喜欢

转载自www.cnblogs.com/azidakahaaa/p/10757553.html