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]求和的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网络对抗技术实验3
- 下一篇: BZOJ1398: Vijos1382寻