Polynomial Round 2022 C. Ice and Fire (构造)

小 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(1t103) - 测试用例数。测试用例说明如下。
每个测试用例的第一行都包含一个整数 n ( 2 ≤ n ≤ 2 ⋅ 1 0 5 ) n ( 2≤n≤2⋅10^5 ) n(2n2105) - 玩家人数。
每个测试用例的第二行包含一个长度为 n − 1 n−1 n1 的二进制字符串 s 。
保证所有测试用例中 n n n 的总和不超过 3 ⋅ 1 0 5 3⋅10^5 3105

输出

对每个测试用例输出 n − 1 n−1 n1 个整数 —— 从 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;
}

这道题提供了一种将总体规律转化为部分规律的做题方法(貌似昨天的题目也是这样构造的?)

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值