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

满分做法:

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. 【转】docker打包python应用

    转自https://www.cnblogs.com/shenh/p/9518343.html 一.前言 容器使用沙箱机制,互相隔离,优势在于让各个部署在容器的里的应用互不影响,独立运行,提供更高的安全 ...

  2. 记一次 .NET 某医院HIS系统 CPU爆高分析

    一:背景 1. 讲故事 前几天有位朋友加 wx 抱怨他的程序在高峰期总是莫名其妙的cpu爆高,求助如何分析? 和这位朋友沟通下来,据说这问题困扰了他们几年,还请了微软的工程师过来解决,无疾而终,应该还 ...

  3. 19 常用API

    API 什么是API? API (Application Programming Interface) :应用程序编程接口 简单来说:就是Java帮我们已经写好的一些方法,我们直接拿过来用就可以了 1 ...

  4. [刷题] PTA 6-10 阶乘计算升级版

    要求: 实现一个打印非负整数阶乘的函数 N是用户传入的参数,其值不超过1000.如果N是非负整数,则该函数必须在一行中打印出N!的值,否则打印"Invalid input" 1 # ...

  5. systemctl list-unit-files

    [CentOS]centos7上查看服务开机启动列表 systemctl list-unit-files centos7上查看服务开机启动列表 命令: systemctl list-unit-file ...

  6. canal 环境搭建 canal 与kafka通信(三)

    canal 占用了生产者 .net core端 使用消费者获取canal 消息 安装 Confluent.Kafka  demo使用 1.3.0 public static void Consumer ...

  7. Linux创建RAID0_实战

    Linux创建RAID实战 一.Linux创建RAID0 RAID0俗称条带,它将两个或多个硬盘组成一个逻辑硬盘,容量是所有硬盘之和 因为是多个硬盘组合成一个,故可并行写操作,写入速度提高,但此方式硬 ...

  8. 1.7 Systemd初始化进程

    1.7 Systemd初始化进程 Linux操作系统的开机过程是这样的,即从BIOS开始,然后进入Boot Loader,再加载系统内核,然后内核进行初始化,最后启动初始化进程.初始化进程作为Linu ...

  9. Linux_部署Ansible

    一.构建Ansible 1.定义清单 清单定义Ansible将要管理的一批主机 这些主机也可以分配到组中,以进行集中管理:组可以包含子组,主机也可以是多个组的成员 清单还可以设置应用到它所定义的主机和 ...

  10. pre -regulator 前端稳压器

    regulator