算法
暴力思路显然
观察到更改操作最多只影响一条链
于是显然
代码
#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
*/
总结
树型结构常见优化套路题
以前也没见过啊