Jeanny
寂兮,寥兮,独立不改,周行而不殆

https://www.luogu.com.cn/problem/P10765

题目描述

本题采用多组数据测试。

现在欣欣有一个从 \(1\)\(n\) 的序列,并想对这个序列进行如下两种操作。

操作一:删去所有的奇数项。

操作二:删去所有的偶数项。

欣欣发现她在进行 \(k\) 次操作后,最后只剩下一个数,但她不知道这个数是多少,于是欣欣来找你求助,她会给你她所进行的 \(k\) 次操作的种类,希望你告诉她最后的那个数是多少。

输入格式

第一行一个正整数 \(T\),表示数据组数。

对于每组数据:

第一行两个整数 \(n\)\(k\),含义如题面所示。

第二行 \(k\) 个整数,代表欣欣依次进行的操作种类,其中 \(1\) 代表操作一,\(2\) 代表操作二。

输出格式

\(T\) 行,每行一个数代表每组数据对应的答案。

样例 #1

样例输入 #1

4
5 2
1 1
8 3
2 2 2 
8 3 
1 1 1
8 3
1 2 1

样例输出 #1

4
1
8
6

提示

【样例解释】

对于第一组数据,序列的变化如下:

\(\{1,2,3,4,5\} \to \{2,4\} \to \{4\}\)

【数据范围】

对于 \(30\%\) 的数据, \(n\le 5\times10^5\)

对于 \(100\%\) 的数据,\(1\le T \le 10\)\(1\le n\le 10^{18}\)

保证对于所有的数据,操作 \(k\) 次后均仅剩下一个数。


分析:

1.首先,开始向正确思路发展的第一步是:想到了,到最后第一个没有被划掉的数字,就是我们要找的答案。
2.第二个接近正确思路的是,公差每次*2。比如,操作是1,则划掉1,3,5,7....公差2
第二次操作还是1,划掉2,6,10,14....公差4
第三次操作是2,划掉8,16 ... 公差8

3.接下来,就没有直击正解了,每次都想先划掉谁。看题解,是每次先保留谁(思维正反面)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
操作1:
2 4 6 8 10 12 14 16 18
操作2:
2 6 10 14 18
操作2:
2 10 18
得到结论:操作2照此下去,会发现首个数字不变。
操作1:
10
会发现,首个数字+公差

所以,每次,求出首个数字是关键。得到结论:
如果是操作1,上一轮的首个数字+公差。
如果是操作2,上一轮的首个数字还是这一轮的首个数字。

#include<bitsstdc++.h>
#define ll long long
using namespace std;
ll n,m,t;
int p;
int main(){
        cin>>t;
        while(t--){
                cin>>n>>m;
                ll a = 1, d = 1;
                for(int i = 1; i <= m; i++){
                        cin>>p;
                        if(p == 1){
                                a = a + d;
                        }
                        d *= 2;
                        // cout<<"a:"<<a<<endl;
                }
                cout<<a<<endl;
        }
        return 0;
}
posted on 2024-07-25 18:49  Jeanny  阅读(28)  评论(0)    收藏  举报