数据结构例题2

题目
我们开一棵线段树记录某个深度中最大的\(dis\)。
同时利用dfs序来让每条长链开一个线段树并且保证不重复。
遍历到某个点时,先处理重儿子,然后把自己加入线段树,计算一端为自己另一端在重儿子子树中的答案。
然后处理每个轻儿子,暴力计算一端在该轻儿子所在子树中,另一端在该点已遍历过的子树中的答案,然后把该轻儿子子树中的所有线段树合并到该点来。

#include<bits/stdc++.h>
#define LL long long
#define pb push_back
#define mp make_pair
#define P pair<int,int>
#define fir first
#define sec second
#define mid ((l+r)>>1)
#define ls p<<1
#define rs p<<1|1
using namespace std;
namespace IO
{
    char ibuf[(1<<21)+1],*iS,*iT;
    char Get(){return (iS==iT? (iT=(iS=ibuf)+fread(ibuf,1,(1<<21)+1,stdin),(iS==iT? EOF:*iS++)):*iS++);}
    int read(){int x=0;char ch=Get();while(ch>57||ch<48)ch=Get();while(ch>=48&&ch<=57)x=x*10+(ch^48),ch=Get();return x;}
}
using namespace IO;
const int N=1000007,M=998244353;
vector<P>E[N];
int len[N],son[N],L[N],R[N],dfn[N],T,n;
LL dis[N],t[N],ans[N],mx[N<<2];
void modify(int p,int l,int r,int x,LL v)
{
    if(l==r) return mx[p]=max(mx[p],v),void();
    (x<=mid? modify(ls,l,mid,x,v):modify(rs,mid+1,r,x,v)),mx[p]=max(mx[ls],mx[rs]);
}
LL query(int p,int l,int r,int L,int R)
{
    if(L<=l&&r<=R) return mx[p];
    return max((L<=mid? query(ls,l,mid,L,R):0),(R>mid? query(rs,mid+1,r,L,R):0));
}
void dfs(int u)
{
    int v,w;
    for(auto x:E[u]) v=x.fir,w=x.sec,dis[v]=dis[u]+w,dfs(v),len[v]+1>len[u]? len[u]=len[son[u]=v]+1:0;
}
void modify(int u,int x,LL v){modify(1,1,n,dfn[u]+x,v);}
LL query(int u,int l,int r){return l=max(l,0),r=min(r,len[u]),(l>r? -1ll<<60:query(1,1,n,dfn[u]+l,dfn[u]+r));}
void dfs2(int u)
{
    dfn[u]=++T;
    if(son[u]) dfs2(son[u]);
    modify(u,0,dis[u]),ans[u]=max(ans[u],query(u,L[u],R[u])-dis[u]);
    int i,v;
    for(auto x:E[u])
    if((v=x.fir)^son[u])
    {
        dfs2(v);
        for(i=0;i<=len[v];++i) ans[u]=max(ans[u],query(u,L[u]-i-1,R[u]-i-1)+(t[i]=query(v,i,i))-(dis[u]<<1));
        for(i=0;i<=len[v];++i) modify(u,i+1,t[i]);
    }
}
int main()
{
    freopen("1.in","r",stdin);
    n=read();int i,u,v,sum=0;
    for(i=1;i<=n;++i) L[i]=read(),R[i]=read(),ans[i]=-1;
    for(v=2;v<=n;++v) u=read(),i=read(),E[u].pb(mp(v,i));
    dfs(1),dfs2(1);
    for(i=1;i<=n;++i) sum=(23333ll*sum+ans[i]+M)%M;
    return !printf("%d",sum);
}

原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/11561571.html

时间: 2024-10-18 20:22:22

数据结构例题2的相关文章

(Updating)【区间操作数据结构例题】

Description 你需要写一种数据结构,来维护一个集合 A(元素可重复),其中需要支持如下操作: Insert(A,x):向集合 A 中插入一个整数 x. Delete(A,x):删除集合 A 中值为整数 x 的元素,若有多个相同的数,只删除一个,若 x 不存则忽略. Max(A):查询集合中最大的元素,若不存在则忽略. Min(A):查询集合中最小的元素,若不存在则忽略. Find(A,x):查询整数 x 的元素是否存在,若存在输出Y,否则输出N. Pred(A,x):查询求 x 的前驱

块状数组

定义: 块状数组是基于分块思想的数据结构,较基于分治思想的数据结构如线段树.平衡树等效率较低,但通用性更强.在块状数组的基础上加以扩展,就可以得到块状链表. 原理: 普通数组在处理一些区间问题时,复杂度通常会退化至O(n).一个朴素的想法就是将这个数组分为若干个子区间,同时维护这些子区间的统计值,如区间和.区间最值等.对于某个子区间,如果操作区间覆盖子区间,则在整体上进行修改并打标记.如果操作区间部分覆盖子区间,则将该块标记下放,对区间中被覆盖部分的元素进行暴力操作. 设数组长度为n,将其分为s

剑指offer-第二章数据结构(数组,字符串,链表,树,栈与队列)及例题

一.数组(最简单的数据结构) 定义:占据一块连续内存并按照顺序存储数据.创建时先指定大小,分配内存. 优点:时间效率高.实现简单的hash(下标为key,对应的数据为value) 缺点:空间效率差.如果我们只在数组中存一个数字,也先分配所有的内存. 扩展:动态数组(解决空间效率差),手段:扩容后,复制内容到新的数组,释放之前的内存.时间性能变差,因此,要尽量减少改变数组容量的次数. 数组与指针:声明一个数组时,数组名字也是一个指针,指向数组的第一个元素. 例题:在一个二维数组中,每一行都按照从左

例题3.1 猜猜数据结构 UVa11995

1.题目描述:点击打开链接 2.解题思路:本题要求根据输入的数据和输出的数据来猜测一种可能的数据结构,备选答案有"栈,队列,优先队列",结果也可能都不是或者不确定.STL中已经有这三种数据结构了,因此直接模拟题意,输出时判断是否对应即可.注意:弹出时要判断一下是否已经为空. 3.代码: #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<algorithm> #include<string

acm常见算法及例题

转自:http://blog.csdn.net/hengjie2009/article/details/7540135 acm常见算法及例题 初期:一.基本算法:     (1)枚举. (poj1753,poj2965)     (2)贪心(poj1328,poj2109,poj2586)     (3)递归和分治法.     (4)递推.     (5)构造法.(poj3295)     (6)模拟法.(poj1068,poj2632,poj1573,poj2993,poj2996)二.图算法

3.1 基础数据结构回顾

例题1  uva11995  http://acm.hust.edu.cn/vjudge/problem/18700 猜测符合哪种数据结构 , 用stl模拟判断. 1 //#define txtout 2 //#define debug 3 #include<bits/stdc++.h> 4 #define mt(a,b) memset(a,b,sizeof(a)) 5 using namespace std; 6 typedef long long LL; 7 const double pi

《挑战程序设计竞赛》2.4 加工并存储数据的数据结构

这个章节一共介绍了几种数据结构:堆,二叉搜索树,并查集. 第一部分 堆. 堆的实现: int heap[maxn]; void push(int x) { int i = sz;//自己结点的编号 while(i > 0) { int p = (i - 1) / 2; if(heap[p] <= x) break; heap[i] = heap[p]; i = p; } heap[i] = x; } int pop() { int ret = heap[0];//取出优先级最高的元素 int

&quot;数据结构翻转课堂&quot;答疑实录——链表

[说明] 本文是<数据结构>翻转课堂在线答疑的实录,由云班课的"答疑/讨论"功能中导出数据整理而成. [重要提示] 下面的内容,按时间从后往前的顺序提供,请直接到文章末尾,倒着看更顺畅. [知识点答疑] 赵鹤2015-09-21 16:38:25 头插法为什么首节点不是后来插入的节点 贺利坚2015-09-21 17:13:56 后加入的成头了. 赵鹤2015-09-21 17:26:04 可是首节点并没有数据域? 贺利坚2015-09-21 18:45:32 先区分下,首

数据结构:树状数组

关于树状数组的概述,可以看一下这篇博客:http://blog.csdn.net/int64ago/article/details/7429868 树状数组是一个可以高效地进行区间统计的数据结构,在思想上类似于线段树,比线段树节省空间,编程复杂度比线段树低,但适用范围比线段树小.主要工作也是查询和更新. 例题:POJ - 2352    (http://poj.org/problem?id=2352) 题目大意:输入n个星星坐标,坐标按y递增顺序输入,y相同按x递增顺序输入.定义一个星星的级别是