K 求和VII lca 字首和)

2021-08-22 16:14:27 字數 2233 閱讀 2998

題目描述

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

輸入第一行包含乙個正整數n,表示樹的節點數。

之後n−1行每行兩個空格隔開的正整數i,j,表示樹上的一條連線點i和點j的邊。

之後一行乙個正整數m,表示詢問的數量。

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

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

輸出對於每組資料輸出一行乙個正整數表示取模後的結果。

樣例輸入

5

1 21 3

2 42 5

21 4 5

5 4 45

樣例輸出

33

503245989

提示

以下用d(i)表示第i個節點的深度。

對於樣例中的樹,有d(1)=0,d(2)=1,d(3)=1,d(4)=2,d(5)=2。

因此第乙個詢問答案為(25+15+05) mod 998244353=33,第二個詢問答案為(245+145+245) mod 998244353=503245989。

對於30%的資料,1≤n,m≤100;

對於60%的資料,1≤n,m≤1000;

對於100%的資料,1≤n,m≤300000,1≤k≤50。

思路:利用前向星見圖bfs過程中,記錄深度維護val[i][j],i表th示當前結點,j表示k,val[i][j]=val[fa[i]][j]+cal(de[i],j),這樣可以維護乙個字首和,後面給出查詢的時候,先用倍增法求出lca,然後val[a][k]+val[b][k]-2*val[lca][k]+cal(lca,k)就是這條路徑上的深度k次方和。

**:(照著狂兵模板改的):)

#include#include#include#include#include#includeusing namespace std;

const int maxn = 300010;

const int deg = 20; //樹的最多層數

const int mod=998244353;

struct edge edge[maxn * 2];

int head[maxn], tot; //前向星鍊錶,head為鏈頭,tot為邊的總數

long long sum_path; //sum_path為全域性變數

void addedge(int u, int v)

void init()

long long k;

long long cal(long long dep,long long k)

return res;

}long long val[maxn][55];

int fa[maxn][deg];//fa[i][j]表示結點i的第2^j個祖先

long long deg[maxn];//深度陣列

void bfs(int root)

for (int i = head[tmp]; i != -1; i = edge[i].next) }}

int lca(int u, int v)

if (tu == tv)return tu; //如果此時在同一結點,說明已經到達最近公共祖先,返回最近最近公共祖先

for (int i = deg - 1; i >= 0; i--)

if (fa[tu][0] == fa[tv][0])

else //否則沒有最近公共祖先,返回-1

return -1;

}bool flag[maxn];

char s[10];

int main()

bfs(1); //以結點1開始bfs遍歷建樹

scanf("%d", &q);

for (int i = 1; i <= q; i++)

return 0;}/*

51 2

2 33 4

3 53

3 4 2

3 5 2

4 5 2

*/

求和 Dirichlet 字首和

題意及題解 神仙gyz,nb就完了 然後,大佬好像沒給 蒟蒻給乙份。upd 之前那個碼跑得太慢了,而且記憶體好像超限了.include include include include using namespace std const int maxn 5e7 10 inline int read ...

1081 子段求和(字首和)

給出乙個長度為n的陣列,進行q次查詢,查詢從第i個元素開始長度為l的子段所有元素之和。例如,1 3 7 9 1,查詢第2個元素開始長度為3的子段和,1 1。3 7 9 19,輸出19。輸入第1行 乙個數n,n為陣列的長度 2 n 50000 第2 至 n 1行 陣列的n個元素。10 9 n i 10...

K倍區間 字首和

第二天叫醒我的不是鬧鐘,是夢想!題目描述 給定乙個長度為n的數列,a1,a2,an,如果其中一段連續的子串行ai,ai 1,aj i j 之和是k的倍數,我們就稱這個區間 i,j 是k倍區間。你能求出數列中總共有多少個k倍區間嗎?輸入 第一行包含兩個整數n和k。1 n,k 100000 以下n行每行...