suoi63 树与路径 (倍增lca)
发现对于某一个点它向上发的一条边,它被经过的次数就是这个点子树数量*不是它子树的数量
那就维护一个前缀和,然后每次拿两个端点和它们的lca的值加一加减一减,再乘上加上的值,就是这次修改后答案的增量
(最后答案还要除以(N*N))
倍增会被卡空间,难受
1 #include<bits/stdc++.h> 2 #define pa pair<int,int> 3 #define lowb(x) ((x)&(-(x))) 4 #define REP(i,n0,n) for(i=n0;i<=n;i++) 5 #define PER(i,n0,n) for(i=n;i>=n0;i--) 6 #define MAX(a,b) ((a>b)?a:b) 7 #define MIN(a,b) ((a<b)?a:b) 8 #define CLR(a,x) memset(a,x,sizeof(a)) 9 #define rei register int 10 using namespace std; 11 typedef long long ll; 12 const int maxn=1000010,mod=998244353; 13 14 inline ll rd(){ 15 ll x=0;char c=getchar();int neg=1; 16 while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();} 17 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 18 return x*neg; 19 } 20 21 struct Edge{ 22 int a,b,l,ne; 23 }eg[maxn*2]; 24 int N,M,egh[maxn],ect,lg[maxn],NP; 25 int fa[maxn][2],dep[maxn],siz[maxn],sum[maxn],num[maxn],ans; 26 27 inline void adeg(int a,int b,int l){ 28 eg[++ect].a=a;eg[ect].b=b;eg[ect].l=l;eg[ect].ne=egh[a];egh[a]=ect; 29 } 30 31 void dfs(int x,int f){ 32 fa[x][0]=f;siz[x]=1;dep[x]=dep[f]+1; 33 for(int i=0;fa[i]&&fa[fa[x][i]][i];i++) fa[x][i+1]=fa[fa[x][i]][i]; 34 for(int i=egh[x];i!=-1;i=eg[i].ne){ 35 if(eg[i].b==f) continue; 36 dfs(eg[i].b,x);siz[x]+=siz[eg[i].b]; 37 }num[x]=1LL*siz[x]*(N-siz[x])%mod; 38 } 39 void dfs2(int x,int f){ 40 sum[x]=(sum[f]+num[x])%mod; 41 for(int i=egh[x];i!=-1;i=eg[i].ne){ 42 if(eg[i].b==f) continue; 43 dfs2(eg[i].b,x); 44 } 45 } 46 47 inline int modp(int x,int p){ 48 int re=1; 49 while(p){ 50 if(p&1) re=1LL*re*x%mod; 51 x=1LL*x*x%mod;p>>=1; 52 }return re; 53 } 54 55 inline int lca(int x,int y){ 56 if(dep[x]<dep[y]) swap(x,y); 57 while(dep[x]!=dep[y]){ 58 x=fa[x][lg[dep[x]-dep[y]]]; 59 }if(x==y) return x; 60 for(int i=lg[dep[x]];i>=0;i--){ 61 if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i]; 62 }return fa[x][0]; 63 } 64 65 int main(){ 66 //freopen("su63.in","r",stdin); 67 rei i,j,k; 68 N=rd(),M=rd();CLR(egh,-1);NP=modp(1LL*N*N,mod-2); 69 for(i=1,j=0,k=2;i<=N;i++){ 70 if(i>=k) j++,k<<=1;lg[i]=j; 71 } 72 REP(i,1,N-1){ 73 int a=rd(),b=rd(),c=rd(); 74 adeg(a,b,c);adeg(b,a,c); 75 }dfs(1,0);dfs2(1,0); 76 int ans=0; 77 for(i=1;i<=ect;i++){ 78 int a=eg[i].a,b=eg[i].b; 79 ans=(1LL*num[dep[a]>dep[b]?a:b]*eg[i].l+ans)%mod; 80 }printf("%d\n",(int)(1LL*ans*NP%mod)); 81 REP(i,1,M){ 82 int a=rd(),b=rd();ll c=rd(); 83 j=lca(a,b);//printf("%d %d %d %d %d %d\n",a,b,j,num[a],num[b],num[j]); 84 ans=((c*2*(sum[a]+sum[b]-sum[j]*2)+ans)%mod+mod)%mod; 85 printf("%d\n",(int)(1LL*ans*NP%mod)); 86 } 87 return 0; 88 }