求一组用于调试的小数据,悬关
查看原帖
求一组用于调试的小数据,悬关
554746
yiming564楼主2024/7/13 22:17

如题,蒟蒻只通过了样例,全部 WA + 2点TLE

求大佬提供一组 hack 数据,或帮助我找出 bug 所在,先行感谢。

#include <bits/extc++.h>

// #define inline	__always_inline
#define inline
#define virt(x) ((x) + stack)
#define real(x) ((x) - stack)
const uint16_t mod = 10007;
uint16_t inv[10008];
int poly_size;
template <typename T>
inline void read(T &x)
{
	char ch;
	for (ch = getchar(); !isdigit(ch); ch = getchar());
	for (x = 0; isdigit(ch); ch = getchar())
		x = x * 10 + ch - '0';
}
inline void read(char &ch)
{
	for (ch = getchar(); !isupper(ch); ch = getchar());
}

class poly_ex_t;

class poly_t
{
public:
	uint16_t x[128];
	poly_t(uint16_t fill) { for (int i = 0; i < 128; i++)	x[i] = fill; }
	poly_t(const poly_ex_t &poly);
	poly_t() {}
	inline uint16_t &operator[](int pos) { return x[pos]; }
	inline const uint16_t &operator[](int pos) const { return x[pos]; }
	inline void operator+=(const poly_t &p)
	{
		for (int i = 0; i < poly_size; i++)
			x[i] = (x[i] + p[i]) % mod;
	}
	inline void operator-=(const poly_t &p)
	{
		for (int i = 0; i < poly_size; i++)
			x[i] = (x[i] + mod - p[i]) % mod;
	}
	inline void operator*=(const poly_t &p)
	{
		for (int i = 0; i < poly_size; i++)
			x[i] = (uint32_t)x[i] * p[i] % mod;
	}
	inline poly_t operator+(const poly_t &p) const
	{
		poly_t ans;
		for (int i = 0; i < poly_size; i++)
			ans[i] = (x[i] + p[i]) % mod;
		return ans;
	}
	inline poly_t operator*(const poly_t &p) const
	{
		poly_t ans;
		for (int i = 0; i < poly_size; i++)
			ans[i] = (uint32_t)x[i] * p[i] % mod;
		return ans;
	}
	inline void FWT(uint16_t type = 1)
	{
		for (int half = 1, step = 2; step <= poly_size; half <<= 1, step <<= 1)
			for (int base = 0; base < poly_size; base += step)
				for (int i = 0; i < half; i++)
				{
					uint16_t a = x[base + i], b = x[base + i + half];
					x[base + i] = (uint32_t)(a + b) * type % mod;
					x[base + i + half] = (uint32_t)(a - b + mod) * type % mod;
				}
	}
	inline void debug()
	{
		for (int i = 0; i < poly_size; i++)
			printf("%d ", x[i]);
		putchar('\n');
	}
};
poly_t poly_unit(1), poly_null;

class poly_ex_t : public poly_t
{
public:
	uint16_t count[128];
	inline void operator*=(const poly_t &p)
	{
		for (int i = 0; i < poly_size; i++)
		{
			assert(p[i] < mod);
			if (p[i])
				x[i] = (uint32_t)x[i] * p[i] % mod;
			else
				count[i]++;
		}
	}
	inline void operator/=(const poly_t &p) 		// ! bug: inv[p[i]] might be undefined
	{
		for (int i = 0; i < poly_size; i++)
		{
			if (inv[p[i]])
				x[i] = (uint32_t)x[i] * inv[p[i]] % mod;
			else
				count[i]--;
		}
	}
};

poly_t::poly_t(const poly_ex_t &poly) 
{
	for (int i = 0; i < 128; i++)
	{
		if (poly.count[i])
			x[i] = 0;
		else
			x[i] = poly.x[i];
	}
}

struct vector_t { poly_t x, y, z; };

struct matrix_t
{
	poly_t a, b, c, d;
	inline matrix_t operator*(const matrix_t &m)
	{
		return (matrix_t){a * m.a, a * m.b + b, a * m.c + c, c * m.b + d + m.d};
	}
	inline vector_t operator*(const vector_t &v)
	{
		return (vector_t){a * v.x + b * v.z, c * v.x + v.y + d * v.z, v.z};
	}
	inline void debug()
	{
		a.debug();
		b.debug();
		c.debug();
		d.debug();
	}
};
matrix_t matrix_unit = {poly_unit, poly_null, poly_null, poly_null};

struct node_t
{
	node_t *parent, *head;
	node_t *hson, *tail;
	int size, start;
};
node_t stack[30001];
std::vector<node_t *> graph[30001];

void build(node_t *u = virt(1))
{
	u->size = 1;
	u->hson = virt(0);
	for (auto &&v : graph[real(u)])
	{
		if (v == u->parent)
			continue;
		v->parent = u;
		build(v);
		u->size += v->size;
		if (u->hson->size < v->size)
			u->hson = v;
	}
}

int timestamp = 0;
void decomposition(node_t *u = virt(1), node_t *head = virt(1))
{
	u->start = timestamp++;
	u->head = head;
	if (u->hson != virt(0))
		decomposition(u->hson, head), u->tail = u->hson->tail;
	else
		u->tail = u;
	for (auto &&v : graph[real(u)])
		if (v != u->parent && v != u->hson)
			decomposition(v, v);
}

class segment_tree_t
{
public:
	struct segment_t
	{
		int l, r;
		inline int size() const { return r - l; }
		inline int mid() const { return l + r >> 1; }
		inline segment_t left() const { return {l, mid()}; }
		inline segment_t right() const { return {mid(), r}; }
		inline bool in(const segment_t &s) const { return s.l <= l && r <= s.r; }
		inline bool out(const segment_t &s) const { return s.r <= l || r <= s.l; }
		inline bool in(int pos) const { return pos == l && r == pos + 1; }
		inline bool out(int pos) const { return pos < l || r <= pos; }
	};
	struct node_t
	{
		node_t *left, *right;
		segment_t s;
		matrix_t m;
	};
	node_t *stack, *top, *root;
	segment_tree_t(int size) { stack = top = root = (node_t *)calloc(size, sizeof(node_t)); }
	~segment_tree_t() { free(stack); }
	inline void push_up(node_t *u) { u->m = u->left->m * u->right->m; }
	void build(node_t *u, const segment_t &s, matrix_t *m)
	{
		u->s = s;
		if (s.size() == 1)
			u->m = m[s.l];
		else
			build(u->left = ++top, s.left(), m), build(u->right = ++top, s.right(), m), push_up(u);
	}
	matrix_t prod(node_t *u, const segment_t &s)
	{
		if (u->s.out(s))
			return matrix_unit;
		if (u->s.in(s))
			return u->m;
		return prod(u->left, s) * prod(u->right, s);
	}
	void set(node_t *u, int pos, matrix_t m)
	{
		if (u->s.out(pos))
			return;
		if (u->s.in(pos))
			u->m = m;
		else
			set(u->left, pos, m), set(u->right, pos, m), push_up(u);
	}
};

int n, q, u, v;
char op;
uint16_t w[30001];
segment_tree_t tree(60000);
poly_t A[30000], C[30000], D[30000];
poly_ex_t B[30000];
matrix_t mat[30000];

void init_A(node_t *u = virt(1))
{
	A[u->start][w[real(u)]] = 1;
	A[u->start].FWT();
	for (auto &&v : graph[real(u)])
	{
		if (v == u->parent)
			continue;
		init_A(v);
		A[u->start] *= (A[v->start] + poly_unit);
	}
}
void init_B(node_t *u = virt(1))
{
	B[u->start][w[real(u)]] = 1;
	B[u->start].FWT();
	for (auto &&v : graph[real(u)])
	{
		if (v == u->parent)
			continue;
		init_B(v);
		if (v != u->hson)
			B[u->start] *= A[v->start] + poly_unit;
	}
}
void init_C(node_t *u = virt(1))
{
	C[u->start] = A[u->start];
	for (auto &&v : graph[real(u)])
	{
		if (v == u->parent)
			continue;
		init_C(v);
		C[u->start] += C[v->start];
	}
}
void init_D()
{
	for (node_t *u = virt(1); u <= virt(n); u++)
		for (auto &&v : graph[real(u)])
			if (v != u->parent && v != u->hson)
				D[u->start] += C[v->start];
}
void debug()
{
	printf("B:\n");
	for (int i = 0; i < timestamp; i++)
	{
		poly_t tmp(B[i]);
		tmp.debug();
	}
	printf("D:\n");
	for (int i = 0; i < timestamp; i++)
		D[i].debug();
	for (int i = 0; i < timestamp; i++)
		mat[i] = tree.prod(tree.root, {i, i + 1});
	printf("Matrix:\n");
	for (int i = 0; i < timestamp; i++)
		printf("%d>\n", i), mat[i].debug();
}
void init_matrix()
{
	for (int i = 0; i < timestamp; i++)
	{
		poly_t B_poly(B[i]);
		mat[i] = {B_poly, B_poly, B_poly, D[i] + B_poly};
	}
	tree.build(tree.root, {0, timestamp}, mat);
}
void init_inv()
{
	inv[1] = 1;
	for (int i = 2; i < mod; i++)
		inv[i] = (uint32_t)(mod - mod / i) * inv[mod % i] % mod;
}
inline vector_t query(node_t *u, int k)
{
	node_t *tail = u->tail;
	vector_t ans = {A[tail->start], C[tail->start], poly_unit};
	matrix_t total = tree.prod(tree.root, {u->start, tail->start});
	return total * ans;
}
void modify(node_t *u, int k)
{
	poly_t origin = poly_null, now = poly_null;
	origin[w[real(u)]] = 1, now[w[real(u)] = k] = 1;
	origin.FWT(); now.FWT();
	B[u->start] /= origin;
	B[u->start] *= now;
	while (u->head->parent)
	{
		node_t *next = u->head->parent;
		vector_t ans = query(u->head, k);
		D[next->start] -= ans.y;
		B[next->start] /= ans.x + poly_unit;
		poly_t B_poly(B[u->start]);
		tree.set(tree.root, u->start, {B_poly, B_poly, B_poly, D[u->start] + B_poly});
		if (u == u->tail)
			C[u->start] = A[u->start] = B_poly;
		ans = query(u->head, k);
		D[next->start] += ans.y;
		B[next->start] *= ans.x + poly_unit;
		u = next;
	}
	poly_t B_poly(B[u->start]);
	if (u == u->tail)
		C[u->start] = A[u->start] = B_poly;
	tree.set(tree.root, u->start, {B_poly, B_poly, B_poly, D[u->start] + B_poly});
}

int main()
{
	init_inv();
	read(n), read(poly_size);
	for (int i = 1; i <= n; i++)
		read(w[i]);
	for (int i = 1; i < n; i++)
	{
		read(u), read(v);
		graph[u].push_back(virt(v));
		graph[v].push_back(virt(u));
	}
	build();
	decomposition();
	init_A();
	init_B();
	init_C();
	init_D();
	init_matrix();
	// debug();
	read(q);
	for (int i = 0; i < q; i++)
	{
		read(op);
		if (op == 'Q')
		{
			read(u);
			auto ans = query(virt(1), u);
			ans.y.FWT(inv[2]);
			printf("%hu\n", ans.y[u]);
		}
		else
		{
			read(u), read(v);
			modify(virt(u), v);
		}
	}
	// debug();
	return 0;
}
2024/7/13 22:17
加载中...