【洛谷5439】【XR-2】永恒(树链剖分,线段树)
【洛谷5439】【XR-2】永恒(树链剖分,线段树)
题面
题解
首先两个点的\(LCP\)就是\(Trie\)树上的\(LCA\)的深度。
考虑一对点的贡献,如果这两个点不具有祖先关系,那么这对点被计算的次数是\(size[u]*size[v]\)次。否则具有祖先关系,假设\(u\)是\(v\)祖先,则是\(size[v]*(n-size[u]+1)\)次。
于是先考虑所有点不具有祖先关系,再减去有祖先关系的情况就好了。
然后现在知道了统计的次数,还需要知道统计的值,显然这个\(len\)可以从\(LCA\)到根节点在每个点都统计一次,那么就是每次链加链求和就行了。
怎么算就看代码吧。。。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
#define ll long long
#define MAX 300300
#define MOD 998244353
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
int n,m,rt,ans,a[MAX];
vector<int> E[MAX],TE[MAX];
int dep[MAX],fa[MAX],sz[MAX],hson[MAX],top[MAX],dfn[MAX],tim;
void dfs1(int u,int ff)
{
fa[u]=ff;dep[u]=dep[ff]+1;sz[u]=1;
for(int v:TE[u])
{
dfs1(v,u),sz[u]+=sz[v];
if(sz[v]>sz[hson[u]])hson[u]=v;
}
}
void dfs2(int u,int tp)
{
top[u]=tp;dfn[u]=++tim;
if(hson[u])dfs2(hson[u],tp);
for(int v:TE[u])if(v!=hson[u])dfs2(v,v);
}
#define lson (now<<1)
#define rson (now<<1|1)
int sum[MAX<<2],tag[MAX<<2];
void Modify(int now,int l,int r,int L,int R,int w)
{
if(L<=l&&r<=R)
{
sum[now]=(sum[now]+1ll*(r-l+1)*w)%MOD;
tag[now]=(tag[now]+w)%MOD;
return;
}
int mid=(l+r)>>1;
if(L<=mid)Modify(lson,l,mid,L,R,w);
if(R>mid)Modify(rson,mid+1,r,L,R,w);
sum[now]=(sum[lson]+sum[rson]+1ll*tag[now]*(r-l+1))%MOD;
}
int Query(int now,int l,int r,int L,int R)
{
if(L==l&&r==R)return sum[now];
int mid=(l+r)>>1,ret=1ll*tag[now]*(R-L+1)%MOD;
if(R<=mid)return (ret+Query(lson,l,mid,L,R))%MOD;
if(L>mid)return (ret+Query(rson,mid+1,r,L,R))%MOD;
return (0ll+ret+Query(lson,l,mid,L,mid)+Query(rson,mid+1,r,mid+1,R))%MOD;
}
void Modify(int u,int w){while(u)Modify(1,1,m,dfn[top[u]],dfn[u],w),u=fa[top[u]];}
int Query(int u){int s=0;while(u)s=(s+Query(1,1,m,dfn[top[u]],dfn[u]))%MOD,u=fa[top[u]];return s;}
void dfs(int u){sz[u]=1;for(int v:E[u])dfs(v),sz[u]+=sz[v];}
void DFS(int u)
{
ans=(ans+1ll*sz[u]*Query(a[u])%MOD)%MOD;
Modify(a[u],MOD-sz[u]);
for(int v:E[u])
{
Modify(a[u],n-sz[v]);
DFS(v);
Modify(a[u],MOD-(n-sz[v]));
}
Modify(a[u],sz[u]);
}
int main()
{
n=read();m=read();
for(int i=1;i<=n;++i)E[read()].push_back(i);
for(int i=1;i<=m;++i)TE[read()].push_back(i);
scanf("%*s");
for(int i=1;i<=n;++i)a[i]=read();
for(int v:TE[1])dfs1(v,0),dfs2(v,v);
dfs(E[0][0]);
for(int i=1;i<=n;++i)ans=(ans+1ll*sz[i]*Query(a[i]))%MOD,Modify(a[i],sz[i]);
for(int i=1;i<=n;++i)Modify(a[i],MOD-sz[i]);
DFS(E[0][0]);
printf("%d\n",ans);
return 0;
}
【洛谷5439】【XR-2】永恒(树链剖分,线段树)的更多相关文章
- 洛谷P4092 [HEOI2016/TJOI2016]树 并查集/树链剖分+线段树
正解:并查集/树链剖分+线段树 解题报告: 传送门 感觉并查集的那个方法挺妙的,,,刚好又要复习下树剖了,所以就写个题解好了QwQ 首先说下并查集的方法趴QwQ 首先离线,读入所有操作,然后dfs遍历 ...
- 洛谷P3313 [SDOI2014]旅行 题解 树链剖分+线段树动态开点
题目链接:https://www.luogu.org/problem/P3313 这道题目就是树链剖分+线段树动态开点. 然后做这道题目之前我们先来看一道不考虑树链剖分之后完全相同的线段树动态开点的题 ...
- 【BZOJ-2325】道馆之战 树链剖分 + 线段树
2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1153 Solved: 421[Submit][Statu ...
- 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树
[BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...
- BZOJ2243 (树链剖分+线段树)
Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...
- POJ3237 (树链剖分+线段树)
Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...
- bzoj4034 (树链剖分+线段树)
Problem T2 (bzoj4034 HAOI2015) 题目大意 给定一颗树,1为根节点,要求支持三种操作. 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子 ...
- HDU4897 (树链剖分+线段树)
Problem Little Devil I (HDU4897) 题目大意 给定一棵树,每条边的颜色为黑或白,起始时均为白. 支持3种操作: 操作1:将a->b的路径中的所有边的颜色翻转. 操作 ...
- Aizu 2450 Do use segment tree 树链剖分+线段树
Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show ...
- 【POJ3237】Tree(树链剖分+线段树)
Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...
随机推荐
- 红黑树之 原理和算法详细介绍(阿里面试-treemap使用了红黑树) 红黑树的时间复杂度是O(lgn) 高度<=2log(n+1)1、X节点左旋-将X右边的子节点变成 父节点 2、X节点右旋-将X左边的子节点变成父节点
红黑树插入删除 具体参考:红黑树原理以及插入.删除算法 附图例说明 (阿里的高德一直追着问) 或者插入的情况参考:红黑树原理以及插入.删除算法 附图例说明 红黑树与AVL树 红黑树 的时间复杂度 ...
- python将oracle数据库保存到excel
上代码: import pandas as pd import SqlHelper.ORACLE as ORA if __name__ == '__main__': #连接数据库 ms = ORA.O ...
- 为什么要学 Python? python该怎么学
很多童鞋对为什么学习Python感到迷茫,小编来跟大家说说学习Python的10个理由,希望可以帮助到大家!!! 摘要: 看完这十个理由,我决定买本python从入门到精通! 如果你定期关注现今的科技 ...
- AppBoxFuture(八): 另类的ORM实现
通常的ORM实现基于配置或注释,由反射或Emit生成相应的Sql语句,然后将Sql发送给数据库解析Sql字符串生成AST再交给优化器处理后执行,返回的数据再经由反射或Emit转换为相应的实体实例. ...
- Tomcat安装、使用(Windows)
一.下载.安装 1.下载 进官网下载 : https://tomcat.apache.org/ 选择自己适合的版本.在这里演示的是下载 Tomcat 7(解压安装版). 2.解压.启动tomcat 解 ...
- QTextStream 读取文件乱码的解决办法
通常都是编码转换的问题,注意如以下红字代码那样设置正确的编码 QFile _file(_f_path); try{ if(_file.open(QIODevice::ReadOnl ...
- [转]Eclipse插件开发之基础篇(1) 插件开发的基础知识
原文地址:http://www.cnblogs.com/liuzhuo/archive/2010/08/13/eclipse_plugin_1_0_2.html 名词翻译 有一些名词在翻译的过程中可能 ...
- 基于socketsever下实现的FTP
# ### 客户端client import socket import json import struct import os sk = socket.socket() sk.connect( ( ...
- [日常] 小白来装机基本概念BIOS与硬盘分区
这两天因为在linux进行测试,先是搞坏了linux的系统,然后在重装linux系统后搞坏了引导.在修复引导的过程中,搞坏了本机的win8系统,再次修复引导与重装linux后,linux可以访问了,w ...
- [PHP] 配置vscode的语法检测消除提示Cannot validate since no PHP executable is set
默认下载完vscode什么都不做,会提示一下信息Cannot validate since no PHP executable is set. Use the setting 'php.validat ...