题目链接:

http://172.16.0.132/senior/#contest/show/2530/1

题目:

EZ同学家里非常富有,但又极其的谦虚,说话又好听,是个不可多得的人才。
        EZ常常在假期环游世界,他准备去N(N<=100000)个国家之多,一些国家有航线连接,由于EZ同学有一定的强迫症,任意两个国家之间都能通过航路直接或间接到达,并且这样的路径仅有一种。(简单来说,这些国家构成了一棵树)
         由于EZ是C国人,因此将C国(1号国家)作为整棵树的根
        每个国家有一个旅游热度A[i]和影响力D[i]。由于目的地有点多,为了避免选择困难症,他给每个国家设置了一个向往值F[i],它等于所有的A[j]之和,满足i国在j国向C国走D[j]步的路径上(经过一条航路算一步,i=j也会被统计,如果D[j]步超过了C国,则超出部分不用管)。
         LYD同学家里有矿,富有程度与EZ不相上下,但他却在宅与现充间摇摆不定。某次机缘巧合,EZ外出旅游刺激了LYD,他决定也要开始旅游。为了避免又被判高重复率导致被取消资格,他将EZ的旅游地图略微做了一点调整,每条航路将有一定的概率出现。
         现在他有Q个询问,每次询问某个国家所在的联通块(由于每条边是一定概率出现,因此它所在的联通块可以是很多种)中所有国家的F[i]值的和的平方的期望(对998244353取模),以此来决定他旅游的目的地。但他极其厌恶繁琐的计算,于是他找到了能算出圆周率并将它倒背下来的你,答应给你丰厚的报酬。家里没矿,老爸也不是X达集团老总的你决定接受他的任务。

题外话:

这题...我查错差不多4小时吧,这一次查错发现了很多代码应该注意的坑点,我无一例外踩了一个遍

题解:

注意1:注意!!!注意!!!期望和的平方不等于和的平方的期望

注意2:每个在EZ的地图中是没有出现概率的说法的,因此每个国家的f值与边的出现概率无关

首先考虑怎么求f数组,对于每个国家在它自己打上一个+的标记,在它的 $d[i]+1$ 级祖先打上-的标记, 就可以直接子树求和了。查询某个位置的 $d[i]+1$ 级祖先可以在 DFS 的时候维护一 个栈,然后对于每个点直接访问栈中相应位置即可,这也是线性的。因此这样就能线性的求出$f$数组

考虑如何计算和的平方,我们不妨以询问的国家作为根重新 DFS 一遍这棵树,考虑 DP, 主要问题就是求两个块以一条出现概率为$ p$ 的边合并时的答案。不妨令原本的块期望和为$a$,并入的块期望和为$b$,根据期望的线性可加性,那么答案是$p(a + b)^2 + (1 − p)a^2 = a^2 + p(2ab +b ^2 )$

这样对于每个节点,维护$k2$数组表示以它为根的子树的期望和,维护$k3$数组表示以它为根的子树的和平方的期望,根据上面那个式子我们就可以合并答案

由于每次询问都要重新DFS,时间复杂度 $O(NQ)$,显然不行(事实上这样就30分)

其实并不需要对于每次询问都重新 DFS 转移,我们不妨仍然以1为根,那么 对于一个节点$i$,我们只需要知道$i$的子树部分的$k2$和$k3$,以及$i$以外的部分的期望和以及和平方的期望,这样就可以维护出i的任意一个儿子的上述信息,我们设$g[i]$表示除i的子树之外的节点的和平方的期望,h[i]表示除i的子树外的节点的期望和,$ans[i]=g[y]+2*h[y]*k2[y]+k3[y]$(注意不能写成$ans[i]=(h[y]+k2[y])^2$,原因参考注意1)

这就是二次扫描与换根的思想

具体怎么从i转移到$i$的儿子呢?我们给i的儿子一个顺序,对第$j$个儿子维护前缀其他儿子的两个信息,再维护后缀其他儿子的两个,这样第j个儿子的信息就相等于合并4部分,$h[x]$,前缀,合并,$f[x]$(代码中表示为$a,b,c,d$)

至于我查错中出现的坑点,一般仅限我的代码,就不赘述了

#include<algorithm>
#include<cstring>
#include<cstdio>
#include<iostream>
using namespace std;
typedef long long ll; const int N=4e5+;
const ll mo=;
const int S=1e7;
int n,tot=,tp;
int h[N],d[N],sta[N],tt[N];
ll cha[N],a[N],k2[N],k3[N],p1[N],p2[N],p3[N],f[N],H[N],G[N],ans[N];
ll Pre2[N],Pre3[N],Bac2[N],Bac3[N];
struct E{
int to,nxt;ll p;
}e[N<<];
inline int gc(){
static char buf[S];
static int len=,pos=;
if (pos==len) pos=,len=fread(buf,,S,stdin);
if (pos==len) exit();
return buf[pos++];
}
inline ll read(){
char ch=gc();ll s=,f=;
while (ch<''||ch>'') {if (ch=='-') f=-;ch=gc();}
while (ch>=''&&ch<='') {s=(s<<)+(s<<)+ch-'';ch=gc();}
return s*f;
}
void link(int u,int v,ll p) {e[++tot]=(E){v,h[u],p};h[u]=tot;}
void dfs1(int x,int pre){
sta[++tp]=x;
cha[x]=(cha[x]+a[x])%mo;
cha[sta[tp-d[x]-]]=(cha[sta[tp-d[x]-]]+(mo-a[x]%mo))%mo;
for (int i=h[x],y;i;i=e[i].nxt){
if ((y=e[i].to)==pre) continue;
dfs1(y,x);
}
tp--;
}
void dfs2(int x,int pre){
f[x]=cha[x];
for (int i=h[x],y;i;i=e[i].nxt){
if ((y=e[i].to)==pre) continue;
dfs2(y,x);
f[x]=(f[x]+f[y])%mo;
}
}
void dfs3(int x,int pre){
k2[x]=f[x];
k3[x]=f[x]*f[x]%mo;
for (int i=h[x],y;i;i=e[i].nxt){
if ((y=e[i].to)==pre) continue;
ll p=e[i].p;
dfs3(y,x);
k3[x]=(k3[x]+*p%mo*k2[x]%mo*k2[y]%mo+p*k3[y]%mo)%mo;
k2[x]=((k2[x]+k2[y])*p%mo+((-p)%mo+mo)%mo*k2[x]%mo)%mo;
}
}
void dfs4(int x,int pre){
Pre2[]=;Pre3[]=;
int j=;
for (int i=h[x],y;i;i=e[i].nxt){
if ((y=e[i].to)==pre) continue;
++j;
tt[j]=i;
ll p=e[i].p;
Pre3[j]=(Pre3[j-]+*p%mo*Pre2[j-]%mo*k2[y]%mo+p*k3[y]%mo)%mo;
Pre2[j]=((Pre2[j-]+k2[y])*p%mo+((-p)%mo+mo)%mo*Pre2[j-]%mo)%mo;
}
Bac2[j+]=;Bac3[j+]=;
for (;j;j--){
int i=tt[j];
int y=e[i].to;
ll p=e[i].p;
Bac3[j]=(Bac3[j+]+*p%mo*Bac2[j+]%mo*k2[y]%mo+p*k3[y]%mo)%mo;
Bac2[j]=((Bac2[j+]+k2[y])%mo*p%mo+((-p)%mo+mo)%mo*Bac2[j+]%mo)%mo; ll a=H[x],b=Pre2[j-],c=Bac2[j+],d=f[x];
ll aa=G[x],bb=Pre3[j-],cc=Bac3[j+],dd=f[x]*f[x]%mo;
G[y]=aa;//一个个合并,不能一起,参考注意1
H[y]=a;
G[y]=(G[y]+bb+*H[y]%mo*b%mo)%mo;
H[y]=(H[y]+b)%mo;
G[y]=(G[y]+cc+*H[y]%mo*c%mo)%mo;
H[y]=(H[y]+c)%mo;
G[y]=(G[y]+dd+*H[y]%mo*d%mo)%mo;
H[y]=(H[y]+d)%mo;
G[y]=G[y]*p%mo;H[y]=H[y]*p%mo;
ans[y]=(G[y]+*H[y]%mo*k2[y]%mo+k3[y])%mo;
}
for (int i=h[x],y;i;i=e[i].nxt){
if ((y=e[i].to)==pre) continue;
dfs4(y,x);
}
}
int main()
{
freopen("travel.in","r",stdin);
freopen("travel.out","w",stdout);
n=read();
for (int i=;i<=n;i++) a[i]=read(),d[i]=read();
ll p;
for (int i=,u,v;i<n;i++){
u=read();v=read();p=read();
link(u,v,p);
link(v,u,p);
}
dfs1(,);
dfs2(,);
dfs3(,);
ans[]=k3[];
dfs4(,);
int q=read();
while (q--){
int s=read();
printf("%lld\n",ans[s]);
}
return ;
}

 

[JZOJ 5911] [NOIP2018模拟10.18] Travel 解题报告 (期望+树形DP)的更多相关文章

  1. [JZOJ 5906] [NOIP2018模拟10.15] 传送门 解题报告(树形DP)

    题目链接: https://jzoj.net/senior/#contest/show/2528/2 题目: 8102年,Normalgod在GLaDOS的帮助下,研制出了传送枪.但GLaDOS想把传 ...

  2. [JZOJ 5912] [NOIP2018模拟10.18] VanUSee 解题报告 (KMP+博弈)

    题目链接: https://jzoj.net/senior/#contest/show/2530/2 题目: 众所周知,cqf童鞋对哲学有着深入的理解和认识,并常常将哲学思想应用在实际生活中,例如锻炼 ...

  3. [JZOJ 5910] [NOIP2018模拟10.18] DuLiu 解题报告 (并查集+思维)

    题目链接: https://jzoj.net/senior/#contest/show/2530/0 题目: LF是毒瘤出题人中AK IOI2019,不屑于参加NOI的唯一的人.他对人说话,总是满口垃 ...

  4. [JZOJ 5895] [NOIP2018模拟10.5] 旅游 解题报告 (欧拉回路+最小生成树)

    题目链接: https://jzoj.net/senior/#main/show/5895 题目: 题解: 有一个好像比较显然的性质,就是每条边最多经过两次 那么我们考虑哪些边需要经过两次.我们把需要 ...

  5. [JZOJ 5894] [NOIP2018模拟10.5] 同余方程 解题报告(容斥)

    题目链接: http://172.16.0.132/senior/#contest/show/2523/0 题目: 题解:(部分内容来自https://blog.csdn.net/gmh77/arti ...

  6. [jzoj 5926] [NOIP2018模拟10.25] naive 的图 解题报告(kruskal重构树+二维数点)

    题目链接: https://jzoj.net/senior/#main/show/5926 题目: 题解: 显然最小的最大路径在最小生成树上(最小生成树=最小瓶颈生成树) 于是我们建出kruskal重 ...

  7. [JZOJ 5893] [NOIP2018模拟10.4] 括号序列 解题报告 (Hash+栈+map)

    题目链接: https://jzoj.net/senior/#main/show/5893 题目: 题解: 考虑暴力怎么做,我们枚举左端点,维护一个栈,依次加入元素,与栈顶元素和栈内第二个元素相同时弹 ...

  8. [JZOJ 5908] [NOIP2018模拟10.16] 开荒(kaihuang)解题报告 (树状数组+思维)

    题目链接: https://jzoj.net/senior/#contest/show/2529/1 题目: 题目背景:尊者神高达作为一个萌新,在升级路上死亡无数次后被一只大黄叽带回了师门.他加入师门 ...

  9. [JZOJ 5909] [NOIP2018模拟10.16] 跑商(paoshang) 解题报告 (圆方树)

    题目链接: https://jzoj.net/senior/#contest/show/2529/2 题目: 题目背景:尊者神高达很穷,所以他需要跑商来赚钱题目描述:基三的地图可以看做 n 个城市,m ...

随机推荐

  1. c1

    dmg和package是安装文件,dmg直接拖进应用程序中,pkg要进行安装. playfround是swift项目. --ios -----oc(面向对象的C) -----swift(oc的封装) ...

  2. iOS 判断是否有权限访问相机,相册

    1.判断用户是否有权限访问相册 #import <AssetsLibrary/AssetsLibrary.h> ALAuthorizationStatus author =[ALAsset ...

  3. 2017-3-4 leetcode 414 485 495

    虽说周末要早起来着,但是日子过得有点奇怪,一不小心就忘掉了... leetcode414 https://leetcode.com/problems/third-maximum-number/?tab ...

  4. NEU 1664 传送(最短路基础 堆优化Dijkstra)

    题目描述 小A最近喜欢上一款游戏:游戏把地图分了一些区域,这些区域可能会重叠,也可能不会. 游戏中有一项传送技能,改传送技能只能将在同一区域的两个地方使用.小A可以利用区域中重叠部分来实现从某一区域到 ...

  5. 锋利Jquery 第一天

    之前一直学习,现在终于有时间来整理一下文档了. 以下文章都是自己学习Jquery 的笔记, 希望能留下痕迹,也希望能帮助到您. 好了开始我的Jquery第一天. 我也是从Hello  wrod!开始的 ...

  6. SQL 数据库性能优化

    http://blog.csdn.net/yzllz001/article/details/54848513 1.  减少数据访问(减少磁盘访问) 2.  返回更少数据(减少网络传输或磁盘访问) 3. ...

  7. c# byte转化为string

    byte[] bt = new byte[] { 10, 11, 33, 44, 2 }; string str=string.Join(",",bt.Select(t=>t ...

  8. Zeplin(for Windows)无缝集成到了 Adobe XD

    Zeplin(for Windows)无缝集成到了 Adobe XD 大约6个月前,推出了 Zeplin 的新Adobe XD CC集成.从那时起,数十万个设计从Adobe XD导出到Zeplin.Z ...

  9. redux原理

    Redux实现原理 不同组件需要依赖同一个数据的时候,就需要状态提升至这些组件的根组件. redux是状态统一管理工具,需要使用它的原因是: 组件之间通信统一管理,方便代码维护. React中有一个特 ...

  10. android studio开发去掉titlebar

    android:theme="@style/AppTheme"换成android:theme="@style/Theme.AppCompat.NoActionBar&qu ...