A
B

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)\)

posted @ 2025-10-22 15:02  MyShiroko  阅读(13)  评论(1)    收藏  举报