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

满分做法:

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. vue中的nextTick

    ​ 今天在浏览elementUI官网时,又一次看到了nextTick,其实nextTIck我已经不是第一次看到了,但之前都没怎么弄懂,这次决定好好研究一番-- 异步说明 vue是异步执行DOM更新的. ...

  2. 游戏中的2D OBB碰撞模型的碰撞算法介绍和实践

    前言 上一篇博文说道,射线与场景中模型上的所有三角形求交时,会大幅度影响效率且花费比较多的时间,因此会采取使用包围盒的形式,进行一个加速求交.在此文中介绍OBB碰撞模型的碰撞算法 OBB的碰撞模型 有 ...

  3. 12.26vj训练补题

    D.City Day 题意:就是给定n,x,y,以及这n天的下雨量ai,要求这一天的下雨量是这一天前x天到后y天的下雨量中最小的.输出最早的(下标最小的)d.保证答案一定存在 思路:直接遍历寻找就好了 ...

  4. CRM的未来发展前景有哪些?

    随着时代的发展,近年来越来越多的国内中小企业开始采用CRM客户关系管理系统,CRM从此不再是大企业的专利,也开始让中小企业得以不断成长.国内CRM行业的发展越来越快, 它的前景是什么?今天小Z就来给大 ...

  5. ES6学习-3 const

    const声明一个只读的常量.一旦声明,常量的值就不能改变,所以在声名时就进行赋值. const的作用域与let命令相同,只在声明所在的块级作用域内有效. const命令声明的常量,同样存在暂时性死区 ...

  6. powercli创建虚拟机步骤及批量创建脚本

    https://pubs.vmware.com/vsphere-51/index.jsp?topic=%2Fcom.vmware.powercli.cmdletref.doc%2FSet-OSCust ...

  7. [bug] ERROR: Can't get master address from ZooKeeper; znode data == null

    排错 访问bigdata111:50070没显示 jps发现hdfs的namenode没启动 查看namenode日志发现9000端口被占用 查找占用端口的进程 杀死进程,或在配置文件中更改端口号 参 ...

  8. kvm总结复习

    一.虚拟化概念 1.虚拟化技术:在计算机技术中,虚拟化(技术)或虚拟技术(英语:Virtualization)是一种资源管理技术,是将计算机的各种实体资源(CPU.内存.磁盘空间.网络适配器等),予以 ...

  9. 05丨实验:安装MongoDB

    https://docs.mongodb.com/manual/tutorial/install-mongodb-on-red-hat/ 源码安装 export PATH=$PATH:/data/mo ...

  10. 编写程序,计算当n=10000,20000,30000...100000时,π的值.求π的近似公式 π=4*(1-1/3+1/5-1/7+1/9-1/11+1/13-...+1/(2n-1)-1/(2n+1))

    该程序是求的 π 近似值,所以随着 i 的增大,值会无线接近于 3.1415926... 代码示例 : package judgment;/** * 编写程序,计算当n=10000,20000,300 ...