BJOI 2012 求和
https://www.luogu.org/problemnew/show/P4427
因为这个题,我交了整整两页...
题目不难,预处理+lca
一个奇坑点:预处理sum的时候,你是不能取模的,因为有可能取模之后sum值变小,而实际上不是,由于你后一步还要做减法
因此就会出锅,导致我爆零一整页正确做法是最后取模,虽然我也不知道为什么这样不会爆炸,300000 * 998244353这都死哪儿去了...
真是血一般的教训啊,取模不能乱取
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #include<climits> #include<vector> #include<cstdlib> #include<ctime> #include<queue> using namespace std; #define mod 998244353 #define maxn 300000 + 10 typedef long long ll; inline ll read() { ll ans = 0,op = 1; char ch = getchar(); while(ch < '0' || ch > '9') { if(ch == '-') op = -1; ch = getchar(); } while(ch >= '0' && ch <= '9') { (ans *= 10) += ch - '0'; ch = getchar(); } return ans * op; } ll power(ll a,ll b) { ll ans = 1,res = a; while(b) { if(b & 1) (ans *= res) %= mod; (res *= res) %= mod; b = b >> 1; } return ans % mod; } struct edge { ll to,next; }e[maxn << 1]; ll fir[maxn],alloc; void adde(ll u,ll v) { e[++alloc].next = fir[u]; fir[u] = alloc; e[alloc].to = v; swap(u,v); e[++alloc].next = fir[u]; fir[u] = alloc; e[alloc].to = v; } ll sum[maxn][60]; ll dep[maxn],f[maxn][31]; void dfs(ll u,ll fa) { dep[u] = dep[fa] + 1; f[u][0] = fa; for(int i = 1;i <= 50;i++) sum[u][i] = sum[fa][i] + power(dep[u],i); for(int i = 1;i <= 20;i++) f[u][i] = f[f[u][i - 1]][i - 1]; for(int i = fir[u];i;i = e[i].next) { ll v = e[i].to; if(v == fa) continue; dfs(v,u); } } ll lca(ll x,ll y) { if(dep[x] < dep[y]) swap(x,y); for(int i = 19;i >= 0;i--) { if(dep[f[x][i]] >= dep[y]) x = f[x][i]; if(x == y) return x; } for(int i = 19;i >= 0;i--) { if(f[x][i] != f[y][i]) { x = f[x][i]; y = f[y][i]; } } return f[x][0]; } ll n,m; int main() { n = read(); for(int i = 1;i <= n - 1;i++) { ll u = read(),v = read(); adde(u,v); } dep[0] = -1; dfs(1,0); m = read(); for(int i = 1;i <= m;i++) { ll u = read(),v = read(),k = read(); ll to = lca(u,v); printf("%lld\n" , ((sum[u][k] + sum[v][k]) - (sum[to][k] + sum[f[to][0]][k])) % mod); } }