2022 China Collegiate Programming Contest (CCPC) Guangzhou Onsite I
I. Infection
n=2000,我们考虑dp
我们转化题意
发现就是找一个连通子块 然后连通块的权重就是其中任何一个点的a[i]其他都是p[i]
但是对于连通块相接的点 我们都要让他是(1-p[i])
因为有选定源点这一个条件 我们本来的dp[i][j]还要加一维[0/1]
表示 第i个节点 我们子树中有j个感染点 并且是否(1/0)选定了源点
对于转移我们能想到的就是
枚举 i,j 根节点dp[u][i][0/1] 子节点的dp[v][j][0/1]乱搞一下
但是i枚举范围变成sz[u] j枚举范围变成sz[v] 之后时间复杂度是O(n)的
然后我们会枚举n个点所以复杂度就是O(n^2)的 跑的飞快
最后注意我们dp只考虑了子树的 我们最后还要让他的父节点是不准感染的
int qmi(int a, int b, int p){ int res = 1; while(b){ if(b & 1) res = res * a % p; a = a * a % p; b >>= 1; } return res; } int inv(int x){ return qmi(x,mod-2,mod); } vector<int>g[N]; int n,a[N],b[N],c[N],p[N],dp[N][2][N],sz[N],ans[N];//dp[i][j][k]表示i节点0/1有源点子树有k个点的概率 void dfs(int u, int fa) { sz[u]=1; dp[u][0][1]=p[u]; dp[u][1][1]=a[u]; dp[u][0][0]=(1-p[u]+mod)%mod; for(auto v:g[u]){ if(v==fa)continue; dfs(v,u); sz[u]+=sz[v]; int tmp[2][n+10]; memset(tmp,0,sizeof tmp); for(int i=1;i<=sz[u]-sz[v];i++){ for(int j=0;j<=sz[v];j++){ (tmp[1][i+j]+=dp[u][1][i]*dp[v][0][j]%mod)%=mod; (tmp[1][i+j]+=dp[u][0][i]*dp[v][1][j]%mod)%=mod; (tmp[0][i+j]+=dp[u][0][i]*dp[v][0][j]%mod)%=mod; } } for(int i=1;i<=sz[u];i++){ dp[u][0][i]=tmp[0][i]; dp[u][1][i]=tmp[1][i]; } } for(int i=1;i<=n;i++) (ans[i]+=dp[u][1][i]*(1-p[fa]+mod)%mod)%=mod; } void solve() { cin >> n; for (int i = 1; i <= n - 1; i++) { int u, v; cin >> u >> v; g[u].push_back(v); g[v].push_back(u); } int sum = 0; for (int i = 1; i <= n; i++) { cin >> a[i] >> b[i] >> c[i]; sum += a[i]; p[i] = (b[i] * inv(c[i])) % mod; sum %= mod; } for(int i=1;i<=n;i++){ a[i]=a[i]*inv(sum)%mod; } dfs(1,0); for(int i=1;i<=n;i++)cout<<ans[i]<<endl; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话