好像用到一些高中数学知识......

满分做法:

case 0:已知a数组求b数组

因为是树状结构,设当前节点x 儿子to

我们从任意一点出发可求出b[root]来,之后我们可以通过寻找两两相连节点的关系来O(n)推出全部的b

我们发现x与y之间只有一条边的贡献不同,就是他们相连的边

(边的贡献即该边节点所在子树通过该点的a权值和)

那么我们就轻松搞掉了......

case 1:已知b求a

设sum[i]为以i为根的子树的a值和,all为总值。

我们首先可以发现b[x]-b[to]的差值可以用sum[to]表示

两者之间的差值其实就是all-sum[to]与sum[to]的差值

那么我们用起高中数学的类似等差数列的东西????

从树上遍历一番将所有的边的x与to的上述式子加和

然后注意记录每个b数组的系数,显然如果是叶子节点为-1,其他也要记录

我们发现化简后

ss[1]*b[1]+........=2*(sum[2]+......sum[n])-all*(n-1)

(ss是系数,all是a的总值)

其中(sum[2]......)总值是2*b[1],之后DFS统计就行了

  1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<string>
5 #include<algorithm>
6 #include<cmath>
7 #include<stack>
8 #include<map>
9 #include<queue>
10 #define ps push_back
11 #define MAXN 210001
12 #define ll long long
13 using namespace std;
14 ll a[MAXN],b[MAXN];
15 ll T,n;
16 ll head[MAXN],tot;
17 struct node{ll to,n;}e[2*MAXN];
18 void add(ll u,ll v)
19 {
20 e[++tot].to=v;e[tot].n=head[u];head[u]=tot;
21 }
22 bool vis[MAXN];ll sum[MAXN];
23 ll fa[MAXN];ll all;
24 void DFS(ll x)
25 {
26 vis[x]=1;
27 all+=a[x];
28 sum[x]=a[x];
29 for(ll i=head[x];i;i=e[i].n)
30 {
31 ll to=e[i].to;
32 if(vis[to]==1)continue;
33 fa[to]=x;
34 DFS(to);
35 sum[x]+=sum[to];
36 b[1]+=sum[to];
37 }
38 }
39 void DFS_findans(ll x)
40 {
41 vis[x]=1;
42 for(ll i=head[x];i;i=e[i].n)
43 {
44 ll to=e[i].to;
45 if(vis[to]==1)continue;
46 b[to]=b[x]-2*sum[to]+all;
47 DFS_findans(to);
48 }
49 }
50 ll orz;
51 void work_a()
52 {
53 memset(sum,0,sizeof(sum));
54 all=0;
55 memset(vis,0,sizeof(vis));
56 DFS(1);
57 memset(vis,0,sizeof(vis));
58 DFS_findans(1);
59 for(ll i=1;i<=n;++i)
60 {
61 printf("%lld ",b[i]);
62 }
63 cout<<endl;
64 }
65 ll chu[MAXN];
66 ll ss[MAXN];
67 void DFS_B(ll x)
68 {
69 vis[x]=1;
70 //printf("x=%lld\n",x);
71 for(ll i=head[x];i;i=e[i].n)
72 {
73 ll to=e[i].to;
74 if(vis[to]==1)continue;
75 fa[to]=x;
76 ss[x]++;
77 ss[to]--;
78 DFS_B(to);
79 }
80 }
81 void DFS_find(ll x)
82 {
83 vis[x]=1;a[x]=sum[x];
84 for(ll i=head[x];i;i=e[i].n)
85 {
86 ll to=e[i].to;
87 if(vis[to])continue;
88 sum[to]=(b[x]-b[to]+all)/2;
89 DFS_find(to);
90 a[x]-=sum[to];
91 }
92 }
93 void work_b()
94 {
95 memset(a,0,sizeof(a));
96 memset(sum,0,sizeof(sum));
97 memset(fa,0,sizeof(fa));
98 all=0;
99 memset(vis,0,sizeof(vis));
100 memset(ss,0,sizeof(ss));
101 DFS_B(1);
102
103 ll pss=0;
104 for(ll i=1;i<=n;++i)
105 {
106 //printf("ss%lld b%lld\n",ss[i],b[i]);
107 pss+=ss[i]*b[i];
108 }
109 all=(2*b[1]-pss)/(n-1);
110 sum[1]=all;
111 //printf("all=%lld\n",all);
112 memset(vis,0,sizeof(vis));
113
114 DFS_find(1);
115
116 for(ll i=1;i<=n;++i)
117 {
118 printf("%lld ",a[i]);
119 }
120 cout<<endl;
121 }
122 int main()
123 {
124 scanf("%lld",&T);
125 while(T--)
126 {
127 memset(a,0,sizeof(a));
128 memset(b,0,sizeof(b));
129 memset(head,0,sizeof(head));
130 memset(vis,0,sizeof(vis));
131 memset(chu,0,sizeof(chu));
132 tot=0;
133 scanf("%lld",&n);
134 for(ll i=1;i<=n-1;++i)
135 {
136 ll x,y;
137 scanf("%lld%lld",&x,&y);
138 add(x,y);add(y,x);
139 chu[x]++;chu[y]++;
140 }
141 scanf("%lld",&orz);
142 if(orz==0)
143 {
144 for(ll i=1;i<=n;++i)
145 {
146 scanf("%lld",&a[i]);
147 }
148 work_a();
149 }
150 else
151 {
152 for(ll i=1;i<=n;++i)
153 {
154 scanf("%lld",&b[i]);
155 }
156 work_b();
157 }
158 }
159 }

【模拟7.27】单(liu_runda学长的神题)的更多相关文章

  1. 通过JS模拟select表单,达到美化效果[demo][转]

    转自: http://www.cnblogs.com/dreamback/p/SelectorJS.html 通过JS模拟select表单,达到美化效果 Demo ------------------ ...

  2. 通过JS模拟select表单,达到美化效果[demo]

    .m-form{background:#fff;padding:50px;font-family:12px/1.5 arial,\5b8b\4f53,sans-serif;} .m-form ul,. ...

  3. .Net模拟提交表单

    2016-09-0210:49:20 以中邮速递API为服务接口,由于提交方式为表单提交,我要获取返回值来处理其他业务,所以一开始尝试采用Js后台获取返回值,但是涉及到跨域请求限制问题,那边服务端接口 ...

  4. 通过HttpURLConnection模拟post表单提交

    通过HttpURLConnection模拟post表单提交 package junit; import java.io.InputStream; import java.net.HttpURLConn ...

  5. nodejs 模拟form表单上传文件

    使用nodejs来模拟form表单进行文件上传,可以同时上传多个文件. 以前项目里有这个方法,最近在客户那里出问题了,同事说,这个方法从来就没管用过,SO,用了一天时间把这个方法给搞出来了(觉得花费的 ...

  6. js模拟form表单提交数据, js模拟a标签点击跳转,避开使用window.open引起来的浏览器阻止问题

    js模拟form表单提交数据, js模拟a标签点击跳转,避开使用window.open引起来的浏览器阻止问题 js模拟form表单提交数据源码: /** * js模拟form表单提交 * @param ...

  7. js_ajax模拟form表单提交_多文件上传_支持单个删除

    需求场景: 用一个input type="file"按钮上传多张图片,可多次上传,可单独删除,最后使用ajax模拟form表单提交功能提交到指定方法中: 问题:由于只有一个file ...

  8. Linux curl 模拟form表单提交信息和文件

    Linux curl 模拟form表单提交信息和文件   curl是一个命令行方式下传输数据的开源传输工具,支持多种协议:FTP.HTTP.HTTPS.IMAP.POP3.TELNET等,功能超级强大 ...

  9. JZOJ 4269. 【NOIP2015模拟10.27】挑竹签

    4269. [NOIP2015模拟10.27]挑竹签 (File IO): input:mikado.in output:mikado.out Time Limits: 1000 ms  Memory ...

随机推荐

  1. ppt技巧--线条

    声明:本文所有截图来源于网易云课堂--<和秋叶一起学PPT>,只做个人复习之用,特此声明! 线条的五种用途:

  2. 【转】风控中的特征评价指标(二)——PSI

    转自:https://zhuanlan.zhihu.com/p/79682292 风控业务背景 在风控中,稳定性压倒一切.原因在于,一套风控模型正式上线运行后往往需要很久(通常一年以上)才会被替换下线 ...

  3. spring mvc @Repository 注入不成功 的原因?

    这样的代码会影响 @Repository 注入

  4. Mac安装python 环境& pychaem

    一.文档说明 在Mac上其实自带python环境,但是很多的library安装python是2.7的版本. 验证:可以在终端Terminal中输入:python 如下图是未安装之前,但是咱们需要在自己 ...

  5. 前端必读:Vue响应式系统大PK

    转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 原文参考:https://www.sitepoint.com/vue-3-reactivity-system ...

  6. [bug] @Test注解无法使用

    参考 https://blog.csdn.net/lixiangxiang666/article/details/83745901

  7. [刷题] 343 Integer Break

    要求 给定一个正数n,可将其分割成多个数字的和,求让这些数字乘积最大的分割方法(至少分成两个数) 示例 n=2,返回1(2=1+1) n=10,返回36(10=3+3+4) 实现 回溯遍历(n^2,超 ...

  8. [刷题] 283 Move Zeros

    要求 将所有的0,移动到vector的后面比如; [1,3,0,12,5] -> [1,3,12,5,0] 实现 第一版程序,时间.空间复杂度都是O(n) 1 #include<iostr ...

  9. Win7通过cmd进入d盘的方法

    Win7通过cmd进入d盘的方法 时间:2016-05-13 15:06:03 作者:yunchun 来源:系统之家  手机查看 评论 我们在使用Win7系统过程中,对于经常使用DOS程序的朋友们来说 ...

  10. 【转载】在python的class中的,self到底是什么?

    在python的class中的,self到底是什么?   答案:self可以理解为一个字典变量,内部存的就是对象的数据属性.如:{'name':'zhang','age':'18'}就是这些. 注意只 ...