U623404 异或树(XorTree)
std
#include<bits/stdc++.h>
#define int long long
#define con putchar_unlocked(' ')
#define ent putchar_unlocked('\n')
#define Blue_Archive return 0
using namespace std;
constexpr int N = 1e5 + 3;
constexpr int mod = 998244353;
constexpr char me[] = "終末なにしてますか?忙しいですか?救ってもらっていいですか?";
int n;
int k0;
int ans[2][N];
int val[2][N];
inline int read()
{
int k = 0,f = 1;
char c = getchar_unlocked();
while(c < '0' || c > '9')
{
if(c == '-') f = -1;
c = getchar_unlocked();
}
while(c >= '0' && c <= '9') k = (k << 3) + (k << 1) + c - '0',c = getchar_unlocked();
return k * f;
}
inline void write(int x)
{
if(x < 0) putchar_unlocked('-'),x = -x;
if(x > 9) write(x / 10);
putchar_unlocked(x % 10 + '0');
}
signed main()
{
// freopen("xortree.in","r",stdin);freopen("xortree.out","w",stdout);
freopen("data.in","r",stdin);freopen("data.out","w",stdout);
k0 = read();
n = read();
bool now = 1;
val[1][k0] = ans[1][k0] = 1;
for(int i = 1,op,x;i <= n;i ++)
{
op = read();
x = read();
if(op == 1)
{
for(int j = 0;j < 8192;j ++)
{
ans[now ^ 1][j] = (val[now][j] + val[now][j ^ x] + ans[now][j ^ x]) % mod;
val[now ^ 1][j] = (2 * val[now][j] + val[now][j ^ x]) % mod;
}
now ^= 1;
}
else write(ans[now][x]),ent;
}
Blue_Archive;
}
data
#include<bits/stdc++.h>
#define int long long
#define con putchar_unlocked(' ')
#define ent putchar_unlocked('\n')
#define Blue_Archive return 0
using namespace std;
constexpr int N = 1e5 + 3;
constexpr int mod = 8192;
constexpr char me[] = "終末なにしてますか?忙しいですか?救ってもらっていいですか?";
int k0;
int n;
inline int read()
{
int k = 0,f = 1;
char c = getchar_unlocked();
while(c < '0' || c > '9')
{
if(c == '-') f = -1;
c = getchar_unlocked();
}
while(c >= '0' && c <= '9') k = (k << 3) + (k << 1) + c - '0',c = getchar_unlocked();
return k * f;
}
inline void write(int x)
{
if(x < 0) putchar_unlocked('-'),x = -x;
if(x > 9) write(x / 10);
putchar_unlocked(x % 10 + '0');
}
signed main()
{
freopen("data.in","w",stdout);
srand(time(0));
k0 = rand() % mod;
n = 8000;
cout << k0 << ' ' << n << '\n';
for(int i = 1,op,x;i <= n;i ++)
{
op = rand() % 3;
if(op <= 1)
{
x = rand() % mod;
cout << 1 << ' ' << x << '\n';
}
else
{
x = rand() % mod;
cout << 2 << ' ' << k0 << '\n';
}
}
Blue_Archive;
}
markdown
## 题目描述
给定一棵有根树 $T$,其初始只包含一个点权为 $k_0$ 的根节点。接下来有 $q$ 次操作如下:
- 形如 1 $x$,代表对于所有当前 $T$ 的**节点**扩张一次:设其权值为 $w$,将一个权值为 $w$ 和一个权值为 $w \bigoplus x$ 的节点加入并作为其儿子节点。
- 形如 2 $x$,代表询问 $T$ 有多少棵子树满足子树内所有节点权值的异或和为 $x$,答案对 998244353 取模。
其中,$\bigoplus$ 表示按位异或算符。
## 输入格式
第一行两个整数 $k_0$ 和 $q$。
接下来 $q$ 行,每行表示一次操作,形式如题目描述。
## 输出格式
对每个第二种操作输出一行一个整数表示答案。
## 输入样例
```cpp
5 3
1 1
1 4
2 1
输出样例
2
数据范围与约定
对于前 \(30\%\) 的数据,保证 \(x,k_0 < 210\),\(q \leq 1000\);
对于上述以外 \(25\%\) 的数据,保证第一种操作的数量不超过 \(13\);
对于上述以外 \(15\%\) 的数据,保证第一种操作的 \(x\) 都相等;
对于 \(100\%\) 的数据,保证 \(1 \leq q \leq 8000\),\(x,k_0 \in [0,213)\)。
与你的日常,便是奇迹

浙公网安备 33010602011771号