日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

LCA+差分【p4427】[BJOI2018]求和

發布時間:2025/3/16 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 LCA+差分【p4427】[BJOI2018]求和 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Description

master 對樹上的求和非常感興趣。他生成了一棵有根樹,并且希望多次詢問這棵樹上一段路徑上所有節點深度的\(k\)?次方和,而且每次的\(k\)?可能是不同的。此處節點深度的定義是這個節點到根的路徑上的邊數。他把這個問題交給了pupil,但pupil 并不會這么復雜的操作,你能幫他解決嗎?

Input

第一行包含一個正整數\(n\),表示樹的節點數。

之后\(n-1\) 行每行兩個空格隔開的正整數\(i,j\),表示樹上的一條連接點\(i\) 和點\(j\)的邊。

之后一行一個正整數\(m\),表示詢問的數量。

之后每行三個空格隔開的正整數\(i, j, k\),表示詢問從點\(i\)到點\(j\) 的路徑上所有節點深度的\(k\) 次方和。由于這個結果可能非常大,輸出其對\(998244353\) 取模的結果。

樹的節點從\(1\) 開始標號,其中\(1\) 號節點為樹的根。

Output

對于每組數據輸出一行一個正整數表示取模后的結果。

wa了好多次,結果發現括號匹配錯了QAQ。

很明顯,這題可以預處理出來\(gw[u][i]\)代表從\(1\)\(u\)路徑上點的深度的\(i\)次方的和.(這是一個前綴和.

然后在\(DFS\)的時候預處理出來倍增數組和\(gw\)數組即可.

預處理\(gw\)數組
\[ gw[u][i]=gw[fa][i]+ksm(depth[u],i) \]
然后根據差分
\[ gw[x][i]+gw[y][i]-(gw[lca_{x,y}][i]+gw[father[lca_{x,y}]][i]) \]
求出\(x,y\)之間的答案即可.

后面的括號寫錯了,難受得一逼.QAQ

代碼

#include<cstdio> #include<algorithm> #include<cctype> #define mod 998244353 #define int long long #define N 300008 #define R register using namespace std; inline void in(int &x) {int f=1;x=0;char s=getchar();while(!isdigit(s)){if(s=='-')f=-1;s=getchar();}while(isdigit(s)){x=x*10+s-'0';s=getchar();}x*=f; } int n,head[N],tot; struct cod{int u,v;}edge[N<<2]; inline void add(int x,int y) {edge[++tot].u=head[x];edge[tot].v=y;head[x]=tot; } int depth[N],f[N][21],gw[N][53]; int q; inline int ksm(int x,int y) {R int res=1;for(;y;y>>=1,x=x%mod*x%mod)if(y&1)res=res%mod*x%mod;return res; } void dfs(int u,int fa) {f[u][0]=fa;depth[u]=depth[fa]+1;for(R int i=1;(1<<i)<=depth[u];i++)f[u][i]=f[f[u][i-1]][i-1];for(R int i=1;i<=52;i++)gw[u][i]=gw[fa][i]+ksm(depth[u],i);for(R int i=head[u];i;i=edge[i].u){if(edge[i].v==fa)continue;dfs(edge[i].v,u);} } inline int lca(int x,int y) {if(depth[x]>depth[y])swap(x,y);for(R int i=20;i>=0;i--)if(depth[x]+(1<<i)<=depth[y])y=f[y][i];if(x==y)return x;for(R int i=20;i>=0;i--){if(f[x][i]==f[y][i])continue;x=f[x][i],y=f[y][i];}return f[x][0]; } signed main() {in(n);for(R int i=1,x,y;i<n;i++)in(x),in(y),add(x,y);depth[1]=-1;dfs(1,1);in(q);for(R int i=1,x,y,k;i<=q;i++){in(x),in(y),in(k);R int la=lca(x,y);printf("%lld\n",(((gw[x][k]+gw[y][k])%mod-(gw[la][k]+gw[f[la][0]][k])%mod)+mod)%mod);} }

轉載于:https://www.cnblogs.com/-guz/p/9843502.html

總結

以上是生活随笔為你收集整理的LCA+差分【p4427】[BJOI2018]求和的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。