小 09 和他的朋友们正在玩游戏。共有 n 名玩家,玩家 i 的温度值是 i 。
环境类型表示为 0 或 1 。当两个棋手在一个特定的环境中对战时,如果环境的类型是 0 ,那么在这个环境中温度值较低的棋手总是获胜;如果环境的类型是 1 ,那么在这个环境中温度值较高的棋手总是获胜。 n−1 个环境的类型组成了一个长度为 n−1 的二进制字符串 s 。
如果有 x 个玩家参与游戏,那么总共会有 x−1 场战斗,而 x−1 个环境的类型将是 s 的前 x−1 个字符。当比赛中还剩下不止一名玩家时,可任意选择剩下的两名玩家进行对战。输掉比赛的玩家将被淘汰出局。战斗 i 的环境类型为 s i s_i si 。
对于从 2 到 n 的每个 x ,请回答以下问题:如果所有温度值不超过 x 的玩家都参加比赛,那么有多少玩家有机会获胜?
输入
每个测试包含多个测试用例。第一行包含一个整数 t ( 1 ≤ t ≤ 1 0 3 ) t ( 1≤t≤10^3 ) t(1≤t≤103) - 测试用例数。测试用例说明如下。
每个测试用例的第一行都包含一个整数 n ( 2 ≤ n ≤ 2 ⋅ 1 0 5 ) n ( 2≤n≤2⋅10^5 ) n(2≤n≤2⋅105) - 玩家人数。
每个测试用例的第二行包含一个长度为 n − 1 n−1 n−1 的二进制字符串 s 。
保证所有测试用例中 n n n 的总和不超过 3 ⋅ 1 0 5 3⋅10^5 3⋅105 。
输出
对每个测试用例输出 n − 1 n−1 n−1 个整数 —— 从 2 2 2 到 n n n 的每个 x x x 都输出有机会获胜的玩家人数。
很容易想到的是:如果串全为1,那么一定是n获胜,如果串全为0,那么一定是1获胜。
那么这时候推广到以1串作为后缀和以0串作为后缀。
如果现在串的后缀是长度为m的1串,现在我们一定只有 m + 1 m+1 m+1 个元素,那么在这 m + 1 m+1 m+1 个里面一定是最大的那个获胜,而有可能成为这个获胜者的人的数量就是 > m > m >m 的选手数量,不管前面怎么取,就算把所有的最大的数全部输掉,最坏的情况也会有 1 1 1 ~ m + 1 m+1 m+1 这些数,那么肯定一定还是 m + 1 m+1 m+1 这个数胜利。
并且在题目给出的条件:可以任意选择比赛人员,的情况下,我们一定可以让所有的m+1到n都被取到。
对于后缀为0的串的结果也是同理。
CODE:
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+10;char s[N];
int n;void solve(){scanf("%d%s",&n,s+2);int now = 1;for(int i = 2;i <= n;i++){if(s[i] == s[i-1])now++; else now = 1;cout << i - now << " ";}puts("");
}int main(){int T;cin >> T;while(T--){solve();}return 0;
}
这道题提供了一种将总体规律转化为部分规律的做题方法(貌似昨天的题目也是这样构造的?)