9.24 NOIP模拟——“单”
来源:互联网 发布:手机淘宝联盟注册账号 编辑:程序博客网 时间:2024/06/02 04:13
单(single)
最开始看到这道题的想法——单源最短路??高斯消元??
最后看题解发现这些都不用……
t=0时
先暴力求出b[1]的值
经过观察可发现
b[son]=b[fa]-suma[son]+(SUMA-suma[son])
=b[fa]+SUMA-2*suma[son]
t=1时
已知 b[son]-b[fa]=SUMA-2*suma[son]
设 k[son]=SUMA-2*suma[son]
因为 sigma suma[i](i不为根)=b[root]
所以 sigma k[i]=(n-1)*SUMA-2*sigma suma[v]=tot
sigma k[i]=(n-1)SUMA-2*b[1]=tot
可得SUMA
a[i]易得
#include<cstdio>#include<cstring>using namespace std;const int N=100000+5,M=2*N;int n;int nxt[M],to[M],head[N],etot;int a[N],b[N],dep[N];int suma[N],SUMA,k[N];void adde(int u,int v){ to[++etot]=v; nxt[etot]=head[u]; head[u]=etot;}void dfs_t0(int u,int fa){ suma[u]+=a[u]; for(int i=head[u];i;i=nxt[i]){ int v=to[i]; if(v==fa) continue; dep[v]=dep[u]+1; dfs_t0(v,u); suma[u]+=suma[v]; }}void dfs_b(int u,int fa){ for(int i=head[u];i;i=nxt[i]){ int v=to[i]; if(v==fa) continue; b[v]=b[u]+SUMA-2*suma[v]; dfs_b(v,u); }}void dfs_t1(int u,int fa){ for(int i=head[u];i;i=nxt[i]){ int v=to[i]; if(v==fa) continue; k[v]=b[v]-b[u]; dfs_t1(v,u); }}void dfs_a(int u,int fa){ int size=0; for(int i=head[u];i;i=nxt[i]){ int v=to[i]; if(v==fa) continue; size+=suma[v]; dfs_a(v,u); } a[u]=suma[u]-size;}void init(){ etot=0,SUMA=0; memset(suma,0,sizeof(suma)); memset(head,0,sizeof(head)); memset(dep,0,sizeof(dep)); memset(k,0,sizeof(k)); memset(b,0,sizeof(b)); memset(a,0,sizeof(a));}int main(){ freopen("single.in","r",stdin); freopen("single.out","w",stdout); int T; scanf("%d",&T); while(T--){ init(); int t; scanf("%d",&n); for(int i=1;i<n;i++){ int u,v; scanf("%d%d",&u,&v); adde(u,v),adde(v,u); } scanf("%d",&t); if(!t){ for(int i=1;i<=n;i++) { scanf("%d",&a[i]); SUMA+=a[i]; } dfs_t0(1,1); //先暴力计算b[1] for(int i=1;i<=n;i++) b[1]+=a[i]*dep[i]; dfs_b(1,1); for(int i=1;i<=n;i++) printf("%d ",b[i]); printf("\n"); } if(t==1){ for(int i=1;i<=n;i++) scanf("%d",&b[i]); dfs_t1(1,1); long long tot=0; for(int i=2;i<=n;i++) tot+=k[i]; suma[1]=SUMA=(2*b[1]+tot)/(n-1); for(int i=2;i<=n;i++) suma[i]=(SUMA-k[i])/2; dfs_a(1,1); /*1是根节点 sigma suma[i](i是整棵树除了根节点1以外的点的集合)=b[1] 可以这么理解吧——当点v又被一颗子树包含了,则说明 它离根节点又多了一次距离 sigma k[i]=(n-1)SUMA-2*sigma suma[v]=tot sigma k[i]=(n-1)SUMA-2*b[1]=tot SUMA=……*/ for(int i=1;i<=n;i++) printf("%d ",a[i]); printf("\n"); } } return 0;}
阅读全文
0 0
- 9.24 NOIP模拟——“单”
- NOIP 模拟赛 单 single
- 9.24NOIP模拟总结
- 9.24NOIP模拟赛
- noip模拟题—跳跃版图 题解
- noip模拟2016——1 取数游戏 dfs 或 状压 noip练习
- C++——NOIP模拟题——葫芦
- C++——NOIP模拟题——方阵
- C++——NOIP模拟题——farm
- C++——NOIP模拟题——寻找位置
- C++——NOIP模拟题——病毒
- C++——NOIP模拟题——间谍网络
- C++——NOIP模拟题——减法
- C++——NOIP模拟题——tree
- C++——NOIP模拟题——cheer
- C++——NOIP模拟题——装果子
- C++——NOIP模拟题——零件加工
- C++——NOIP模拟题——种树
- 某安全浏览器竟然也被查出高危漏洞?开源安全问题不容忽视
- 191. Number of 1 Bits
- 需求、开发和测试的“三足鼎立”
- 日常小结篇-重载/重写
- 用正则截取字符串中的某个字段
- 9.24 NOIP模拟——“单”
- Keil的使用方法
- IOS-iframe 嵌套某一个页面,点击跳转下一个页面不能操作页面中的任何事件
- PLSQL来Oracle创建表空间和创建用户
- External Storage之SDCard操作
- [nginx] Nginx 的 Rewrite 规则实例
- 直接插入排序
- 阿里云发布自研商用关系型数据库POLARDB
- JAVA源码分享:基于Apache POI,将List<T>内封装的实体类信息写出到磁盘Excel文件(20170925)