1 条题解
-
0
自动搬运
来自洛谷,原作者为

wind_whisper
wind_whisper & KHIN Tie Tie /qq |鹏北海,凤朝阳,又携书剑路茫茫搬运于
2025-08-24 22:11:24,当前版本为作者最后更新于2022-06-08 19:15:16,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
一道被洛谷遗忘的闹鬼题。
第一眼:ddp?看一眼通过人数:怕不是道神题吧...
开始使用大脑:...这暴力跳重链更新不就是 吗...
再看看通过人数...我一定是哪里假了...
再想想我的做法...哪里假了啊...写写试试?提交...过了...
???
连题解都没有??那我水一篇吧...总所周知,树剖每个节点到根的重链个数严格不超过 的。
所以对于每个点维护其 集合内所有点点权的乘积与加和,再对每个链头维护链上所有点点权的乘积与加和,修改的时候暴力维护即可。#include<bits/stdc++.h> #include<string> using namespace std; #define ll long long #define ull unsigned ll #define debug(...) fprintf(stderr,__VA_ARGS__) #define ok debug("OK\n") inline ll read() { ll x(0),f(1);char c=getchar(); while(!isdigit(c)) {if(c=='-') f=-1;c=getchar();} while(isdigit(c)) {x=(x<<1)+(x<<3)+c-'0';c=getchar();} return x*f; } const int N=1e6+100; const int mod=99991; bool mem1; inline ll ksm(ll x,ll k){ ll res(1); while(k){ if(k&1) res=res*x%mod; x=x*x%mod; k>>=1; } return res; } int n,m,k; vector<int>e[N]; ll mul[N],sum[N],cur[N],ori[N]; ll top_mul[N],top_sum[N],ni[N]; int top[N],fa[N],siz[N],hson[N]; int a[N]; void dfs1(int x,int f){ fa[x]=f; siz[x]=1; for(int to:e[x]){ if(to==f) continue; dfs1(to,x); siz[x]+=siz[to]; if(siz[to]>siz[hson[x]]||(siz[to]==siz[hson[x]]&&to<hson[x])) hson[x]=to; } return; } bool tag[N]; void dfs2(int x,int tp){ top[x]=tp; mul[x]=1; if(x==top[x]) top_mul[x]=1; if(hson[x]) dfs2(hson[x],tp); for(int to:e[x]){ if(to==hson[x]) continue; dfs2(to,to); } if(e[x].empty()) cur[x]=a[x],tag[x]=1; else cur[x]=a[x]?mul[x]:sum[x]; if(!tag[x]) return; if(top[x]>1){ mul[fa[top[x]]]=mul[fa[top[x]]]*cur[x]%mod; sum[fa[top[x]]]=(sum[fa[top[x]]]+cur[x])%mod; tag[fa[top[x]]]=1; } top_mul[top[x]]=top_mul[top[x]]*cur[x]%mod; top_sum[top[x]]=(top_sum[top[x]]+cur[x])%mod; //printf("x=%d cur=%lld\n",x,cur[x]); return; } inline void upd(int x){ if(!tag[x]) return; ori[x]=cur[x]; if(e[x].empty()) cur[x]=a[x]; else cur[x]=a[x]?mul[x]:sum[x]; top_mul[top[x]]=top_mul[top[x]]*ni[ori[x]]%mod; top_sum[top[x]]=(top_sum[top[x]]+mod-ori[x])%mod; top_mul[top[x]]=top_mul[top[x]]*cur[x]%mod; top_sum[top[x]]=(top_sum[top[x]]+cur[x])%mod; if(top[x]>1){ mul[fa[top[x]]]=mul[fa[top[x]]]*ni[ori[x]]%mod; sum[fa[top[x]]]=(sum[fa[top[x]]]+mod-ori[x])%mod; mul[fa[top[x]]]=mul[fa[top[x]]]*cur[x]%mod; sum[fa[top[x]]]=(sum[fa[top[x]]]+cur[x])%mod; upd(fa[top[x]]); } } bool mem2; signed main() { #ifndef ONLINE_JUDGE freopen("a.in","r",stdin); freopen("a.out","w",stdout); #endif for(int i=1;i<mod;i++) ni[i]=ksm(i,mod-2); n=read();m=read(); for(int i=2;i<=n;i++) e[read()].push_back(i); for(int i=1;i<=n;i++) a[i]=read(); dfs1(1,0); dfs2(1,1); for(int i=1;i<=m;i++){ int op=read(),x=read(); if(op==1){ int w=read(); a[x]=w; upd(x); } else if(op==2){ a[x]^=1; upd(x); } else printf("%lld %lld\n",top_sum[top[x]],top_mul[top[x]]); } return 0; } /* 3 1 2 3 3 1 1 1 */
- 1
信息
- ID
- 4472
- 时间
- 1500ms
- 内存
- 128MiB
- 难度
- 6
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者