> 文章列表 > 【CF1774C】Ice and Fire(构造,DP)

【CF1774C】Ice and Fire(构造,DP)

【CF1774C】Ice and Fire(构造,DP)

【题目描述】
nnn个人,第iii个人的温度iii
环境类型为000111,若环境为000,则温度低的人胜利,若环境为111,则温度高的人胜利,n−1n-1n1个环境类型组成一个长为n−1n-1n1的二进制串sss
xxx个人参与游戏,则共有x−1x-1x1场战斗,环境类型即为sss的前x−1x-1x1个元素。在有不少于222个人时,任选222个人进行战斗,其中第iii场战斗的环境类型为sis_isi
对于任意一个从222nnnxxx,如果所有温度不超过xxx的人都参与比赛,有多少人有机会获胜(活到最后)?

【输入格式】
第一行一个整数t(1≤t≤103)t(1\\le t\\le 10^3)t(1t103),表示测试样例的数量。
对于每组测试样例第一行输入一个整数n(2≤n≤2×105)n(2\\le n\\le 2\\times 10^5)n(2n2×105),表示玩家个数。
第二行输入一个长度为n−1n-1n1的字符串sss
数据保证每组测试用例中的nnn的和不超过3×1053\\times 10^53×105

【输出格式】
对于每组测试用例,输出一行共n−1n-1n1个整数,即对于从222nnn的每一个xxx,有多少人有机会获胜。

【输入样例】

2
4
001
4
101

【输出样例】

1 1 3
1 2 3

【说明/提示】
In the first test case, for x=2x=2x=2 and x=3x=3x=3, only the player whose temperature value is 111 can be the winner. For x=4x=4x=4 , the player whose temperature value is 2,3,42,3,42,3,4 can be the winner.

【分析】


假设最后一场的环境为111,即温度大的人赢,那么温度为111的人即使活到了最后一场也必输。

同理,如果最后kkk场的环境都为111,那么有k(1∼k)k(1\\sim k)k(1k)个人一定没机会赢,另外的x−kx-kxk名选手都有机会赢,因为只有温度大于等于k+1k+1k+1的人才可能连续战胜温度为1∼k1\\sim k1k的人活到最后。

那么如何保证k+1∼xk+1\\sim xk+1x名选手都有机会活到最后kkk场呢?假设要使选手i(k+1≤i≤x)i(k+1\\le i\\le x)i(k+1ix)活到最后kkk场,只需要先让剩下的在k+1∼xk+1\\sim xk+1x中的选手互相对战,由于第k−1k-1k1场环境一定为000,那么让剩下的另一名选手jjj1∼k1\\sim k1k中的选手打,被淘汰,那么iii就活到了最后kkk场。

反之如果最后kkk场的环境都为000也同样可以证明有机会赢的人数为x−kx-kxk


【代码】

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;int main()
{int T, n;string s;cin >> T;while (T--){cin >> n >> s;cout << 1 << ' ';for (int i = 1, k = 1; i < s.size(); i++)  // k表示最长相同后缀的长度{if (s[i] == s[i - 1]) k++;else k = 1;cout << i + 2 - k << ' ';  // 第1 ~ i + 2名选手参赛}cout << endl;}return 0;
}