Playoff Tournament

算法#

暴力思路显然
观察到更改操作最多只影响一条链
于是显然

代码#

#include <bits/stdc++.h>
const int MAXLEN = 263000;


int k;
std::string Result;

int q;
int Match;
char New_Result;

int pows[20] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288};

int State[MAXLEN];


int Left_Son[MAXLEN];
int Right_Son[MAXLEN];
int Fa[MAXLEN];
void solve1_init()
{
    for (int i = 1; i <= pows[k] - 2; i++)
    {
        if (i % 2)
            Left_Son[i + pows[k - 1] - i / 2] = i, Fa[i] = i + pows[k - 1] - i / 2;
        else
            Right_Son[i + pows[k - 1] - i / 2] = i, Fa[i] = i + pows[k - 1] - i / 2;
    }

    Fa[pows[k] - 1] = -1;
    for (int i = 1; i <= pows[k - 1]; i++)
    {
        Left_Son[i] = -1;
        Right_Son[i] = -1;
    }

    for (int i = 1; i <= pows[k - 1]; i++)
    {
        if (Result[i] == '0' || Result[i] == '1')
        {
            State[i] = 1;
        }
        else
        {
            State[i] = 2;
        }
    }

    for (int i = pows[k - 1] + 1; i <= pows[k] - 1; i++)
    {
        if (Result[i] == '0')
        {
            State[i] = State[Left_Son[i]];
        }
        else if (Result[i] == '1')
        {
            State[i] = State[Right_Son[i]];
        }
        else
        {
            State[i] = State[Left_Son[i]] + State[Right_Son[i]];
        }
    }
}


void solve1()
{
    Result[Match] = New_Result;

    for (int i = Match; ~i; i = Fa[i])
    {
        if(Result[i] == '0' && i > pows[k - 1])
        {
            State[i] = State[Left_Son[i]];
        }
        else if (Result[i] == '1' && i > pows[k - 1])
        {
            State[i] = State[Right_Son[i]];
        }else if (i > pows[k - 1]){
            State[i] = State[Left_Son[i]] + State[Right_Son[i]];
        }else{
            State[i] = (Result[i] == '0' || Result[i] == '1') ? 1 : 2;
        }
    }

    printf("%d\n", State[pows[k] - 1]);
}

int main()
{

    //freopen("tournament.in", "r", stdin);
    //freopen("tournament.out", "w", stdout);

    scanf("%d", &k);
    std::cin >> Result;
    Result = ' ' + Result;

    scanf("%d", &q);
    solve1_init();
    for (int i = 1; i <= q; i++)
    {
        scanf("%d", &Match);
        getchar();
        scanf("%c", &New_Result);


        if(q <= 100 && k <= 6)
            solve1();
        else
            solve1();
    }

    return 0;
}

/*
3
0110?11
6
5 1
6 ?
7 ?
1 ?
5 ?
1 1

1
2
3
3
5
4
*/

总结#

树型结构常见优化套路题
以前也没见过啊

posted @   Yorg  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
more_horiz
keyboard_arrow_up light_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示