小 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;
}
这道题提供了一种将总体规律转化为部分规律的做题方法(貌似昨天的题目也是这样构造的?)