折纸
折纸(模拟 \(\star \))
- 时限:\(1s\) 内存:\(256M\)
Descrption
- 小 \(s\) 很喜欢折纸。
- 有一天,他得到了一条很长的纸带,他把它从左向右均匀划分为\(N\)个单位长度,并且在每份的边界处分别标上数字 \(0\sim n\)。
- 然后小 \(s\) 开始无聊的折纸,每次他都会选择一个数字,把纸带沿这个数字当前所在的位置翻折(假如已经在边界上了那就相当于什么都不做)。
- 小 \(s\) 想知道\(M\)次翻折之后纸带还有多长。
Input
- 输入包含多组数据,第一为一个正整数 \(T,0<T\le 10\)。
- 接下来,每组数据包括两行。
- 第一行包含两个正整数\(N\)和\(M\),表示纸带的长度和操作的次数。
- 第二行包含\(M\)个整数\(D_i\),其中\(D_i\)表示第\(i\)次选择的数字。
Output
- 每组数据输出一行,只有一个数字,即纸带最后的长度。
Sample Input
2
5 2
3 5
5 2
3 2
Sample Output
2
2
Hint
- 100%的数据中\(N \le 10^{18}, M \le 3000\);。
- 来源:
分析
- 我们可以模拟每一次折叠情况,对每一次折叠来说,向左或向右折叠都一样,但为了避免越界,我们选择短的一方向长的一方折叠。
- 我们不用考虑非折叠点,每一次折叠,如果我们以 \(a[i]\) 为中心向右折叠,这对未处理的折叠点 \(a[j]\) 来说,如果 \(a[j]<a[i]\) 其折叠后必然和 \(a[i]\) 右边的某点重合 \(x\),\(x-a[i]=a[i]-a[j]\Rightarrow x=2*a[i]-a[j]\) 。我们直接把 \(a[j]\) 修改为 \(x\) 不影响后面的结果。向左折叠类似,自己推即可。
- 注意千万不要只往一个方向折叠,不然会挂掉两个点,为了卡这个情况,老姚可是花了不少时间 😃。
hzoi