BJOI2018 Summation

Although a preprocessingwaterQuestion, but I don't know what's wrong recently, and the code frequently has bugs. There is actually no case where the subscript is out of bounds to -1.

#include <cstdio>
#include <cstring>
#define N 300010
typedef long long ll;
const ll mo = 998244353;
inline char gc() {
    static char now[1<<16], *S, *T;
    if(S == T) {T = (S = now) + fread(now, 1, 1<<16, stdin); if(S == T) return EOF;}
    return *S++;
}
inline int read() {
    int x = 0, f = 1; char c = gc();
    while(c < '0' || c > '9') {if(c == '-') f = -1; c = gc();}
    while(c >= '0' && c <= '9') {x = x * 10 + c - 48; c = gc();}
    return x * f;
}
int n, m; ll sum[N][55];
inline ll qpow(ll a, ll b, ll c) {
	ll ret = 1;
	while(b) {
		if(b & 1) {--b; ret = ret * a % c;}
		a = a * a % c; b>>= 1;
	}
	return ret;
}
int head[N], cnt = 1; struct adj {int to, next;}e[N<<1];
inline void ins(int x, int y) {e[++cnt].to = y; e[cnt].next = head[x]; head[x] = cnt;}
int d[N], f[N][19];
void dfs(int x, int fa, int dep) {
	f [x] [0] = fa; d [x] = dep;
	for(int i = head[x]; i; i = e[i].next) if(e[i].to != fa) dfs(e[i].to, x, dep + 1);
}
inline void init() {
	dfs(1, 1, 0);
	for(int j = 1; j <= 18; ++j)
		for(int i = 1; i <= n; ++i) f[i][j] = f[f[i][j - 1]][j - 1];
}
inline int lca(int x, int y) {
	if(d[x] < d[y]) {int tmp = x; x = y; y = tmp;}
	for(int i = 18; i >= 0; --i) if(d[x] - d[y] >= (1<<i)) x = f[x][i];
	if(x == y) return x;
	for(int i = 18; i >= 0; --i) if(f[x][i] != f[y][i]) {x = f[x][i]; y = f[y][i];}
	return f[x][0];
}
int main() {
	n = read();
	for(int i = 0; i <= n; ++i)
		for(int j = 0; j <= 50; ++j)
			if(!i) sum[i][j] = 0;
			else sum[i][j] = (sum[i - 1][j] + qpow(i, j, mo)) % mo;
	memset(head, 0, sizeof(head));
	for(int i = 1; i < n; ++i) {int x = read(), y = read(); ins(x, y); ins(y, x);}
	init(); m = read();
	for(int i = 1; i <= m; ++i) {
		int x = read(), y = read(), k = read();
		int z = lca(x, y);
		if(z == 1) {printf("%lld\n", (sum[d[x]][k] + sum[d[y]][k]) % mo); continue;}
		ll ans = ((sum[d[x]][k] - sum[d[z] - 1][k] + sum[d[y]][k] - sum[d[z]][k]) % mo + mo) % mo;
		printf("%lld\n", ans);
	}
	return 0;
}
In addition, it is not very good to use fast power when preprocessing sum... Open an array to memorize the current power of each number, and multiply it directly to update.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325727029&siteId=291194637