求助,倍增法LCA+预处理k次方前缀和,WA 0分
查看原帖
求助,倍增法LCA+预处理k次方前缀和,WA 0分
9198
处1a2b3c4d楼主2021/5/27 13:54

RT

#include<bits/stdc++.h>
#define pb push_back
using namespace std;
typedef long long ll;
const int MAXN = 3e5+5;
const int MOD = 998244353;
vector<int> G[MAXN];
int fa[MAXN][20];
int dep[MAXN], maxd=0;
ll sum[MAXN][55];
void dfs(int p, int f){
    fa[p][0]=f;
    dep[p]=dep[f]+1;
    maxd=max(maxd,dep[p]);
    for(auto i:G[p]){
        if(i!=f){
            dfs(i,p);
        }
    }
    for(int i=1;i<20;i++){
        fa[p][i]=fa[fa[p][i-1]][i-1];
    }
}
int lca(int a, int b){
    if(dep[a]>dep[b]) swap(a,b);
    int delta=dep[b]-dep[a], tg=0;
    while(delta){
        if(delta&1) b=fa[b][tg];
        delta>>=1; tg++;
    }
    if(a==b) return a;
    else{
        for(int i=19;i>=0;i--){
            if(fa[a][i]!=fa[b][i]){
                a=fa[a][i]; b=fa[b][i];
            }
        }
        return fa[a][0];
    }
}
int main(){
    int n,u,v,m,w;
    scanf("%d",&n);
    for(int i=1;i<n;i++){
        scanf("%d%d",&u,&v);
        G[u].pb(v);
        G[v].pb(u);
    }
    dfs(1,1);
    for(int i=1;i<=52;i++) sum[0][i]=0;
    for(int i=1;i<MAXN;i++){
        sum[i][0]=1;
        for(int j=1;j<=52;j++){
            sum[i][j]=(sum[i][j-1]*i)%MOD;
        }
    }
    for(int i=1;i<MAXN;i++){
        for(int j=1;j<=52;j++){
            sum[i][j]=(sum[i][j]+sum[i-1][j])%MOD;
        }
    }
    scanf("%d",&m);
    for(int i=1;i<=m;i++){
        scanf("%d%d%d",&u,&v,&w);
        int q=dep[lca(u,v)]-1, p=dep[u]-1, r=dep[v]-1;
        printf("%lld\n",((sum[p][w]+sum[r][w])%MOD-(sum[q][w]+sum[q-1][w])%MOD+MOD)%MOD);
    }
    return 0;
}

2021/5/27 13:54
加载中...