【LGP5439】【XR-2】永恒
是个傻题
显然枚举每一条路径经过了多少次,如果\(u,v\)在树上不是祖先关系的话经过\((u,v)\)这条路径的路径条数就是\(sum_u\times sum_v\)
于是我们子树大小映射到\(\rm Trie\)上去,树形\(\rm dp\)一下就可以求出所有点对产生的贡献了
但是这样祖先关系的节点就算错了,我们发现这也非常好算,\(\rm dfs\)的时候拿\(\rm LCT\)维护一下就好了
代码
#include<bits/stdc++.h>
#define re register
inline int read() {
char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
const int maxn=3e5+5;
const int mod=998244353;
struct E{int v,nxt;}e[maxn];
inline int qm(int x) {return x>=mod?x-mod:x;}
inline int dqm(int x) {return x<0?x+mod:x;}
int n,m,num,rt,ans,sm[maxn],head[maxn],d[maxn];
char S[maxn];
struct Trie {
E e[maxn<<1];
int head[maxn],num,v[maxn],deep[maxn];
inline void add(int x,int y) {
e[++num].v=y;e[num].nxt=head[x];head[x]=num;
}
void pdfs(int x) {
for(re int i=head[x];i;i=e[i].nxt) deep[e[i].v]=deep[x]+1,pdfs(e[i].v);
}
void dfs(int x,int dep) {
for(re int i=head[x];i;i=e[i].nxt) {
dfs(e[i].v,dep+1);
ans=qm(ans+1ll*dep*v[x]%mod*v[e[i].v]%mod);
v[x]=qm(v[x]+v[e[i].v]);
}
}
}T;
struct LinkCutTree {
int fa[maxn],ch[maxn][2],rev[maxn],tag[maxn],st[maxn],top,sum[maxn],a[maxn],sz[maxn];
inline int nrt(int x) {return ch[fa[x]][1]==x||ch[fa[x]][0]==x;}
inline void pushup(int x) {
sz[x]=1+sz[ch[x][0]]+sz[ch[x][1]];sum[x]=a[x];
if(ch[x][0]) sum[x]=qm(sum[x]+sum[ch[x][0]]);
if(ch[x][1]) sum[x]=qm(sum[x]+sum[ch[x][1]]);
}
inline void work(int x,int v) {
a[x]=qm(a[x]+v);tag[x]=qm(tag[x]+v);
sum[x]=qm(sum[x]+1ll*sz[x]*v%mod);
}
inline void pushdown(int x) {
if(tag[x]) {
if(ch[x][0]) work(ch[x][0],tag[x]);
if(ch[x][1]) work(ch[x][1],tag[x]);
tag[x]=0;
}
if(rev[x]) {
rev[x]=0;rev[ch[x][0]]^=1;rev[ch[x][1]]^=1;
std::swap(ch[ch[x][0]][0],ch[ch[x][0]][1]);
std::swap(ch[ch[x][1]][0],ch[ch[x][1]][1]);
}
}
inline void rotate(int x) {
int y=fa[x],z=fa[y],w=ch[y][1]==x,k=ch[x][w^1];
if(nrt(y)) ch[z][ch[z][1]==y]=x;
ch[x][w^1]=y,ch[y][w]=k;
pushup(y),pushup(x);fa[k]=y,fa[y]=x,fa[x]=z;
}
inline void splay(int x) {
int y=x;top=0;st[++top]=x;
while(nrt(y)) y=fa[y],st[++top]=y;
while(top) pushdown(st[top--]);
while(nrt(x)) {
int y=fa[x];
if(nrt(y)) rotate((ch[fa[y]][1]==y)^(ch[y][1]==x)?x:y);
rotate(x);
}
}
inline void access(int x) {
for(re int y=0;x;y=x,x=fa[x])
splay(x),ch[x][1]=y,pushup(x);
}
inline void mrt(int x) {
access(x);splay(x);rev[x]^=1;std::swap(ch[x][0],ch[x][1]);
}
inline void link(int x,int y) {
mrt(x);fa[x]=y;T.add(x,y);
}
inline void split(int x,int y) {
mrt(x);access(y);splay(y);
}
inline void ins(int x,int y,int v) {
split(x,y);v=dqm(v);work(y,v);
}
inline int query(int x,int y) {
split(x,y);
return dqm(sum[y]-a[y]);
}
}lct;
inline void add(int x,int y) {
e[++num].v=y;e[num].nxt=head[x];head[x]=num;
}
void dfs1(int x) {
sm[x]=1;
for(re int i=head[x];i;i=e[i].nxt) dfs1(e[i].v),sm[x]+=sm[e[i].v];
}
void dfs2(int x) {
ans=qm(ans+1ll*sm[x]*lct.query(d[x],1)%mod);
for(re int i=head[x];i;i=e[i].nxt) {
lct.ins(1,d[x],n-sm[e[i].v]-sm[x]);
dfs2(e[i].v);
lct.ins(1,d[x],sm[x]+sm[e[i].v]-n);
}
}
int main() {
n=read(),m=read();
for(re int x,i=1;i<=n;i++) {
x=read();if(x) add(x,i);else rt=i;
}
for(re int x,i=1;i<=m;i++) {
x=read();if(x) lct.link(x,i);
}
dfs1(rt);scanf("%s",S+1);T.pdfs(1);
for(re int i=1;i<=n;i++) {
d[i]=read();
ans=qm(ans+1ll*sm[i]*T.deep[d[i]]%mod*T.v[d[i]]%mod);
T.v[d[i]]=qm(T.v[d[i]]+sm[i]);
}
T.dfs(1,0);dfs2(rt);printf("%d\n",ans);
return 0;
}
【LGP5439】【XR-2】永恒的更多相关文章
- XD, XR, DR 股票
股权登记日与除权除息日 所以,如果投资者想得到一家上市公司的分红.配股权,就必须弄清这家公司的股权登记日在哪一天,否则就会失去分红.配股的机会. 股权登记日后的第一天就是除权日或除息日,这一天或以后购 ...
- hihocoder #1179 : 永恒游戏 暴力
#1179 : 永恒游戏 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://hihocoder.com/problemset/problem/11 ...
- Android内存、性能是程序永恒的话题
内存.性能是程序永恒的话题,实际开发中关于卡顿.OOM也经常是打不完的两只老虎,关于卡顿.OOM的定位方法和工具比较多,这篇文章也不打算赘述了,本章主要是来整理一下JVM的内存模型以及Java对象的生 ...
- 文件:因为懂你,所以永恒 - 零基础入门学习Python028
文件:因为懂你,所以永恒 让编程改变世界 Change the world by program 因为懂你,所以永恒 大多数的程序都遵循着:输入->处理->输出的模型,首先接受输入数据,然 ...
- NSA永恒之蓝病毒,如何通过360工具修复?
简介: NSA武器库的公开被称为是网络世界"核弹危机",其中有十款影响Windows个人用户的黑客工具,包括永恒之蓝.永恒王者.永恒浪漫.永恒协作.翡翠纤维.古怪地鼠.爱斯基摩卷. ...
- “永恒之蓝"漏洞的紧急应对--毕业生必看
早上6点多起床了,第一次起这么早,昨天晚上12点多,看到了一则紧急通知,勒索软件通过微软"永恒之蓝"漏洞针对教育网进行了大规模的攻击,而且有很多同学中招.中招后的结果如下图所示. ...
- 由"永恒之蓝"病毒而来的电脑科普知识
永恒之蓝病毒事件: 继英国医院被攻击,随后在刚刚过去的5月12日晚上20点左右肆虐中国高校的WannaCry勒索事件,全国各地的高校学生纷纷反映,自己的电脑遭到病毒的攻击,文档被加密,壁纸遭到篡改,并 ...
- iOS屏幕适配 支持新手机 iPhone XR iPhone XS 超简单
随着苹果爸爸发布了 超牛叉的iPhone iPhone X .iPhone XR.iPhone XS .iPhone XS Max.开发者的适配工作要开始了. 停,
- js判断iPhone XS、iPhone XS Max、iPhone XR
// iPhone X.iPhone XS && window.screen.width === && window.screen.height === ; // iP ...
随机推荐
- Ubuntu下安装Samba服务器
闲来无聊尝试自己安装下Samba服务器,使本机和虚拟机可以无障碍传输文件(虽然用VMwaretools可传,但总感觉麻烦,而且速度欠佳) 首先,同安装qemu一样,在安装之前要确定你的系统apt列表已 ...
- 实现Comparator接口和Comparable接口,以及Map按value排序 ,map遍历
继承Comparator接口,重写compare()方法 import java.util.ArrayList; import java.util.Arrays; import java.util.C ...
- python re 正則匹配規則
- Docker、Kubernetes(k8s)与OpenShift之间的关系
openshift是基于容器计数搭建的一个云平台.这里的容器技术即包括Docker和Kunbernetes.如下图所示,OPenshift底层以Docker作为容器引擎驱动,以Kubernetes作为 ...
- Git 学习第一天
本文是根据廖雪峰老师的git教程记录的学习笔记,特此说明,原教程链接https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c ...
- ArcGis基础——把类别代码替换成对应中文名称的方法
挂接! 上面是答案,展开一下就是做一个Excel对照表,就两列,代码与中文名称.然后用类别代码字段匹配挂接. 别傻傻找vbs/py代码,不知道拐个弯.
- 转载:mysql sql_safe_updates 分析
今天看到一个很实用的功能,mysql_safe_updates. 只是对功能做了转载,具体原理可以看一下 delete from table t where true ; update t set c ...
- 从零开始搭建系统1.7——FTP安装及配置
1.安装vsftp软件包 [root@localhost usr]# yum install -y vsftpd 2.先备份vsftpd的默认配置文件 [root@localhost usr]# cd ...
- mongo 分片集群的搭建
MongoDB版本当前使用的MongoDB版本为4.2.0,下载地址.https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-4.2. ...
- loj2000[SDOI2017]数字表格
题意:f为Fibnacci数列.求$\prod_{1<=i<=n,1<=j<=m} f[gcd(i,j)]$. n,m<=1e6. 标程: #include<bit ...