两个子任务真的是坑……考试的时候想到了60分的算法,然而只拿到了20分(各种沙雕错,没救了……)。

算法1:

对于测试点1,直接n遍dfs即可求出答案,复杂度O(n^2),然而还是有好多同学跑LCA/最短路……

期望得分10;

算法2(搬运题解,因为这个我没有想到……):

t=1的数据最直接的想法是枚举所有可能的a[]数组判断是否可行.第2个测试点n<=5,1<=a[i]<=20.注意20^5=3200000,直接暴力搜索a[i]的取值是可以承受的,可以通过第2个测试点,期望得分10分,结合算法1,期望得分20分.

算法3:

对于测试点6,7。我们可以发现每个点的dis都有联系,这不就是二次扫描与换根吗(具体看代码理解)。结合算法2期望得分40;

 void dfs2(int x,int fa)
{
for(int i=f(x);i;i=n(i))
if(v(i)!=fa)
{
b[v(i)]=b[x];
b[v(i)]-=sum[v(i)];
b[v(i)]+=sum[x]-sum[v(i)];
sum[x]-=sum[v(i)];
sum[v(i)]+=sum[x];
dfs2(v(i),x);
sum[v(i)]-=sum[x];
sum[x]+=sum[v(i)];
}
}

第二次扫描的代码

算法4:

t=1的数据中,b数组的表达式写出来之后,每个b[i]对应一个关于a[i]和树上两点距离的方程,例如b[1]=dis(1,1)*a[1]+dis(1,2)*a[2]+dis(1,3)*a[3]+...+dis(1,n)*a[n],于是可以列出n个方程用高斯消元求解,可以通过第2,3,4个测试点,期望得分30分,结合算法3,期望得分60分。要注意的一点是,高斯消元中要注意这句话‘if(fabs(sa[j][i])>fabs(sa[i][i]))’,本人死于此……还有不少人死于强制类型转化的四舍五入,其实printf("%0.0lf")即可;

之后的算法题解写的已经很清晰了,我觉得我也写不了这么清楚,就直接搬运了。

算法5:

对于测试点5,树退化为1条链。这个测试点的作用主要在于启发选手想到正解的思路(然而我并没有什么启发……)。

t=0时,我们分别考虑编号小于i和大于i的点对b[i]的贡献.那么离得越远的点对答案的贡献越大.分别考虑每条边对答案的贡献,那么左侧的某条边对答案的贡献就是这条边左侧全部a[i]之和.实际上,我们对a[i]分别求取两次前缀和,两次后缀和即可完成对b[i]的计算.

记suf(i)为a[i]+a[i+1]+....+a[n-1]+a[n],pre(i)为a[1]+a[2]+...+a[i-1]+a[i],则b[i]=pre(1)+pre(2)+...+pre(i-1)+suf(i+1)+suf(i+2)+...+suf(n-1)+suf(n)

考虑t=1的情况.

我们知道suf(2)+suf(3)+...+suf(n)的值(即b[1]),知道pre(1) + suf(3) + suf(4) +...+suf(n)的值(即b[2]),知道pre(1)+pre(2)+suf(4)+...+suf(n)的值(即b[3]),注意到这些式子有很多项是一样的,考虑作差.可以得到下面的式子:

b[2]-b[1]=pre(1)-suf(2),b[3]-b[2]=pre(2)-suf(3).....b[i+1]-b[i]=pre(i)-suf(i+1)

这些式子是有实际意义的,考虑从b[1]变到b[2]时答案的变化量,变化的就是1和2之间连边的贡献.

同时,记SUM=a[1]+a[2]+...+a[n-1]+a[n],显然pre(i)+suf(i+1)=SUM,因此pre(i)=SUM-suf(i+1),将上面式子中所有pre换成suf,我们就知道了

SUM-2*suf(2) ,SUM-2*suf(3)...SUM-2*suf(n)的取值。

注意我们将n个式子作差之后得到了n-1个等式,实际上是丢弃了一些信息,只保留了b[i]之间的相对大小而忽略了b[i]自身的数值大小.于是考虑b[1]=suf(2)+suf(3)+suf(4)+... +suf(n),我们发现suf(2)到suf(n)都恰好出现了一次,而之前得到了n-1个形如SUM-2*suf(i)的式子,将这n-1个式子相加,suf(2),suf(3)...suf(n)前面的系数都是2,SUM的系数为(n-1),那么把这个式子加上2*b[1],就得到了(n-1)*SUM,将求得的SUM代入之前的n-1个式子可以得到suf(2),suf(3),suf(4)......suf(n),差分一下即可得到a数组.

时间复杂度O(n),可以通过第5个测试点.推出这个做法,树上的做法也就不难想了.

算法6(满分算法):

考虑树上的问题.

t=0的时候,我们可以先暴力计算出b[1],然后从b[1]出发开始dfs,由某个点的父亲的b[i]推出这个点的b[i],变化的是这个点和父亲的连边的贡献,也就是这条边两侧的点的a[i]之和的差值.

t=1的时候,顺着链上的思路,我们先随便找一个点为根建树,将有边直接相连的两个点的b[i]作差.设x的父亲为prt[x],以x为根的子树中所有a[i]之和为sum(x), SUM=a[1]+a[2]+...+a[n-1]+a[n],那么b[x]-b[prt[x]]=(SUM-sum(x))-sum(x).

同链的情况一样,得到n-1个式子,将树根的b[i]也列出式子,可以求出全部a[i]之和,然后就可以根据之前的式子推出所有的a[i],和链的做法类似,不再赘述.

 #include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define MAXN 100010
#define int LL
#define LL long long
#define esp 1e-8
#define ma(x) memset(x,0,sizeof(x))
using namespace std;
struct edge
{
int u,v,nxt;
#define u(x) ed[x].u
#define v(x) ed[x].v
#define n(x) ed[x].nxt
}ed[MAXN*];
int first[MAXN],num_e;
#define f(x) first[x]
int T,n,t;
LL a[MAXN],b[MAXN];
LL dis[MAXN],sum[MAXN];
LL SUM,suf[MAXN];
LL SUM_2suf[MAXN];
LL SUM_2sum[MAXN];
LL TSUM=; int map[][];
double sa[][],sb[];
void GS()
{
for(int i=;i<=n;i++)
{
for(int j=i;j<=n;j++)
if(fabs(sa[j][i])>fabs(sa[i][i]))
{
for(int k=;k<=n;k++)
swap(sa[i][k],sa[j][k]);
swap(sb[i],sb[j]);
}
for(int j=;j<=n;j++)
{
if(j==i)continue;
if(fabs(sa[i][i])<=esp)continue;
double cal=sa[j][i]/sa[i][i];
for(int k=;k<=n;k++)
sa[j][k]-=sa[i][k]*cal;
sb[j]-=sb[i]*cal;
}
}
}
void dfs(int x,int fa)
{
sum[x]=a[x];
for(int i=f(x);i;i=n(i))
if(v(i)!=fa)
{
dis[v(i)]=dis[x]+;
dfs(v(i),x);
sum[x]+=sum[v(i)];
}
}
void dfs2(int x,int fa)
{
for(int i=f(x);i;i=n(i))
if(v(i)!=fa)
{
b[v(i)]=b[x];
b[v(i)]-=sum[v(i)];
b[v(i)]+=sum[x]-sum[v(i)];
sum[x]-=sum[v(i)];
sum[v(i)]+=sum[x];
dfs2(v(i),x);
sum[v(i)]-=sum[x];
sum[x]+=sum[v(i)];
}
}
void dfs3(int x,int fa)
{
if(x!=)SUM_2sum[x]=b[x]-b[fa];
for(int i=f(x);i;i=n(i))
if(v(i)!=fa)
dfs3(v(i),x);
}
void dfs4(int x,int fa)
{
if(x==)sum[x]=SUM;
else sum[x]=(SUM-SUM_2sum[x])/;
a[x]=sum[x];
for(int i=f(x);i;i=n(i))
if(v(i)!=fa)
{
dfs4(v(i),x);
a[x]-=sum[v(i)];
}
}
inline int read();
inline void add(int u,int v);
signed main()
{
// freopen("in.txt","r",stdin); T=read();
while(T--)
{
ma(sum);ma(first);num_e=;ma(dis);ma(a);ma(b);
ma(map);ma(sa);ma(sb);ma(suf);SUM=;ma(SUM_2suf);
ma(SUM_2sum);TSUM=;
bool pd=;
n=read();int u,v;
for(int i=;i<n;i++)
{
u=read(),v=read();
if(v!=u+)pd=;
add(u,v),add(v,u);
}
t=read();
if(t==)
{
for(int i=;i<=n;i++)a[i]=read();
if(n<=)
{
for(int i=;i<=n;i++)
{
dis[i]=;
dfs(i,);
for(int j=;j<=n;j++)b[i]+=a[j]*dis[j];
}
for(int i=;i<=n;i++)
printf("%lld ",b[i]);
puts("");
continue;
}
else
{
dis[]=;dfs(,);
for(int i=;i<=n;i++)b[]+=dis[i]*a[i];
dfs2(,);
for(int i=;i<=n;i++)
printf("%lld ",b[i]);
puts("");
continue;
}
}
if(t==)
{
for(int i=;i<=n;i++)b[i]=read();
if(n<=)
{
for(int i=;i<=n;i++)
{
dis[i]=;dfs(i,);
for(int j=;j<=n;j++)map[i][j]=dis[j];
}
for(int i=;i<=n;i++)sb[i]=b[i];
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)sa[i][j]=map[j][i];
GS();
for(int i=;i<=n;i++)
printf("%0.0lf ",sb[i]/sa[i][i]);
puts("");
continue;
}
if(pd)
{
for(int i=;i<=n;i++)SUM_2suf[i]=b[i]-b[i-];
LL tem=;
for(int i=;i<=n;i++)tem+=SUM_2suf[i];
tem+=b[]*;
SUM=tem/(n-);
for(int i=;i<=n;i++)suf[i]=(SUM-SUM_2suf[i])/;
suf[]=SUM;suf[n+]=;
for(int i=;i<=n;i++)a[i]=suf[i]-suf[i+];
for(int i=;i<=n;i++)
printf("%lld ",a[i]);
puts("");
continue;
}
else
{
dfs3(,);
for(int i=;i<=n;i++)TSUM+=SUM_2sum[i];
TSUM+=b[]*;
SUM=TSUM/(n-);
dfs4(,);
for(int i=;i<=n;i++)
printf("%lld ",a[i]);
puts("");
continue;
}
}
}
}
inline int read()
{
int s=;char a=getchar();
while(a<''||a>'')a=getchar();
while(a>=''&&a<=''){s=s*+a-'';a=getchar();}
return s;
}
inline void add(int u,int v)
{
++num_e;
u(num_e)=u;
v(num_e)=v;
n(num_e)=f(u);
f(u)=num_e;
}

HZOJ 单的更多相关文章

  1. HZOJ 20190727 T2 单(树上dp+乱搞?+乱推式子?+dfs?)

    考试T2,考试时想到了40pts解法,即对于求b数组,随便瞎搞一下就oxxk,求a的话,很明显的高斯消元,但考试时不会打+没开double挂成10pts(我真sb),感觉考试策略还是不够成熟,而且感觉 ...

  2. H5单页面手势滑屏切换原理

    H5单页面手势滑屏切换是采用HTML5 触摸事件(Touch) 和 CSS3动画(Transform,Transition)来实现的,效果图如下所示,本文简单说一下其实现原理和主要思路. 1.实现原理 ...

  3. 快速构建H5单页面切换骨架

    在Web App和Hybrid App横行的时代,为了拥有更好的用户体验,单页面应用顺势而生,单页面应用简称`SPA`,即Single Page Application,就是只有一个HTML页面的应用 ...

  4. ASP.NET Aries 入门开发教程9:业务表单的开发

    前言: 经过前面那么多篇的列表的介绍,终于到了大伙期待的表单开发了. 也是本系列的最后一篇文章了! 1:表单页面的权限设置与继承 对于表单页面,权限的设置有两种: 1:你可以选择添加菜单(设置为不显示 ...

  5. 【CSS进阶】伪元素的妙用--单标签之美

    最近在研读 <CSS SECRET>(CSS揭秘)这本大作,对 CSS 有了更深层次的理解,折腾了下面这个项目: CSS3奇思妙想 -- Demo (请用 Chrome 浏览器打开,非常值 ...

  6. bootstrap + requireJS+ director+ knockout + web API = 一个时髦的单页程序

    也许单页程序(Single Page Application)并不是什么时髦的玩意,像Gmail在很早之前就已经在使用这种模式.通常的说法是它通过避免页面刷新大大提高了网站的响应性,像操作桌面应用程序 ...

  7. 探索ASP.NET MVC5系列之~~~3.视图篇(下)---包含常用表单和暴力解猜防御

    其实任何资料里面的任何知识点都无所谓,都是不重要的,重要的是学习方法,自行摸索的过程(不妥之处欢迎指正) 汇总:http://www.cnblogs.com/dunitian/p/4822808.ht ...

  8. SignalR快速入门 ~ 仿QQ即时聊天,消息推送,单聊,群聊,多群公聊(基础=》提升)

     SignalR快速入门 ~ 仿QQ即时聊天,消息推送,单聊,群聊,多群公聊(基础=>提升,5个Demo贯彻全篇,感兴趣的玩才是真的学) 官方demo:http://www.asp.net/si ...

  9. jQuery学习之路(8)- 表单验证插件-Validation

    ▓▓▓▓▓▓ 大致介绍 jQuery Validate 插件为表单提供了强大的验证功能,让客户端表单验证变得更简单,同时提供了大量的定制选项,满足应用程序各种需求.该插件捆绑了一套有用的验证方法,包括 ...

随机推荐

  1. 关于C# 异步

    关于C# 异步操作整理 按照个人的理解, 写一个接口用Task异步操作(态度:接受并且学习,您提出宝贵的经验与理解,我会认真学习): 在主线程中调用异步方法,如果主线程依赖异步方法的返回值那么你一定会 ...

  2. Netty源码分析--Channel注册(上)(五)

    其实在将这一节之前,我们来分析一个东西,方便下面的工作好开展. 打开启动类,最开始的时候创建了一个NioEventLoopGroup 事件循环组,我们来跟一下这个. 这里bossGroup, 我传入了 ...

  3. RestTemplate使用不当引发的问题分析

    背景 系统: SpringBoot开发的Web应用: ORM: JPA(Hibernate) 接口功能简述: 根据实体类ID到数据库中查询实体信息,然后使用RestTemplate调用外部系统接口获取 ...

  4. Hive 学习之路(七)—— Hive 常用DML操作

    一.加载文件数据到表 1.1 语法 LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (p ...

  5. Java NIO 学习笔记(三)----Selector

    目录: Java NIO 学习笔记(一)----概述,Channel/Buffer Java NIO 学习笔记(二)----聚集和分散,通道到通道 Java NIO 学习笔记(三)----Select ...

  6. 关于Jvm类加载机制,这一篇就够了

    前言 一个月没更新了,这个月发生了太多的事情,导致更新的频率大大降低,不管怎样收拾心情,技术的研究不能落下! jvm作为每个java程序猿必须了解的知识,博主推荐一本书<深入理解Java虚拟机& ...

  7. SqlServer执行计划

    MSSQLSERVER执行计划详解 * from ServiceInvoke; --创建时间聚集索引扫描 * from AdoLog; --主键ID聚集索引扫描 --2.根据聚集索引排序-性能提升 - ...

  8. Fabric1.4源码解析:链码实例化过程

    之前说完了链码的安装过程,接下来说一下链码的实例化过程好了,再然后是链码的调用过程.其实这几个过程内容已经很相似了,都是涉及到Proposal,不过整体流程还是要说一下的. 同样,切入点仍然是fabr ...

  9. Ceph原理动画演示

    动图生动刻画Ceph的基本原理之集群搭建及数据写入流程:)

  10. mysql查询语句出现sending data耗时解决

    在执行一个简单的sql查询,表中数据量为14万 sql语句为:SELECT id,titile,published_at from spider_36kr_record where is_analyz ...