題目描述
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行每行...