对于每种信仰维护一棵动态开点线段树就行了- #include <cstdio> #include <cctype> #include <cstring> #include <algorithm> using namespace std; typedef long long LL; inline void read(int &num) { char ch; int flg=1; while(!isdigit(ch=getchar()))if(ch=='…
https://www.lydsy.com/JudgeOnline/problem.php?id=3531 首先这题意要求树链上的最大值以及求和,其树链剖分的做法已经昭然若揭 问题在于这次的信息有宗教条件下的限制,导致不那么容易维护. 第一个想法自然是对于每一个宗教都建一颗线段树,看一下数据范围,宗教的范围是1e5,N的范围也是1e5,又好像空间不那么允许. 事实上可以采用动态线段树的方法节省一波空间,整个做法就变得科学了起来. 如果不是因为我的愚蠢在树剖的重链部分写挂了导致T了很久,这题还是很…
题目链接 CF915E Physical Education Lessons 题解 动态开点线段树 代码 /* 动态开点线段树 */ #include<cstdio> #include<cstring> #include<algorithm> inline int read() { int x = 0,f = 1; char c = getchar() ; while(c < '0' || c > '9')c = getchar(); while(c <…
题意 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教.绝地教都是常见的信仰. 为了方便,我们用不同的正整数代表各种宗教, S国的居民常常旅行.旅行时他们总会走最短路,并且为了避免麻烦,只在信仰和他们相同的城市留宿.当然旅程的终点也是信仰与他相同的城市.S国政府为每个城市标定了不同的旅行评级,旅行者们常会记下途中(包括起点和终点)留宿过的城市的评级总和或最大值. 在S国的历史上常会发生以下几种…
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3531 分析: 对于每个颜色(颜色<=10^5)都建立一颗线段树 什么!那么不是MLE了吗! 类似于主席树时候的操作,采用动态开点线段树,对于某个插入操作,从对应颜色的线段树根节点开始对应往下找,一但找到了空节点,则新建节点继续往下,知道元节点. 这样对于每个点,顶多开一条链 所以总的空间是nlogn的 对于原问题的几个操作,修改权值.询问和.询问最大值都是树链剖分的经典操作 还有个操…
感觉动态开点线段树空间复杂度好优秀呀 树剖裸题 把每个宗教都开一颗线段树就可以了 但是我一直TLE 然后调了一个小时 为什么呢 因为我 #define max(x, y) (x > y ? x : y) 看起来好像可以减少常数的样子 我也是这么想的(作死 事实上 ans = max(ans, query(x, y)) 类似这种语句中 query(x, y)会计算两次 然后就GG了 这告诉我们还是好好用库里的函数吧 #include <cstdio> #include <algori…
题意 题目链接 Sol 树链剖分板子 + 动态开节点线段树板子 #include<bits/stdc++.h> #define Pair pair<int, int> #define MP(x, y) make_pair(x, y) #define fi first #define se second //#define int long long #define LL long long #define Fin(x) {freopen(#x".in",&quo…
Description S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教.绝地教都是常见的信仰.为了方便,我们用不同的正整数代表各种宗教,  S国的居民常常旅行.旅行时他们总会走最短路,并且为了避免麻烦,只在信仰和他们相同的城市留宿.当然旅程的终点也是信仰与他相同的城市.S国政府为每个城市标定了不同的旅行评级,旅行者们常会记下途中(包括起点和终点)留宿过的城市的评级总和或最大值.    在S国…
题面传送门 sb 出题人不在题面里写 \(b_i=0\) 导致我挂成零蛋/fn/fn 首先考虑树链剖分将路径问题转化为序列上的问题,因此下文中简称"位置 \(i\)"表示 DFS 序为 \(i\) 的点,\(a_i,b_i\) 分别借指 DFS 为 \(i\) 的点的 \(a_i,b_i\).那么每次操作可以看作将一段区间上的位置清空并加上这段区间上所有位置的贡献.注意到这个清空形式单一,具体来说如果设 \(t_i\) 表示上一次位置 \(i\) 被清空的时刻,那么对于一个时刻 \(T…
首先,对于从每个点出发的路径,答案一定是过这个点的路径所覆盖的点数.然后可以做树上差分,对每个点记录路径产生总贡献,然后做一个树剖维护,对每个点维护一个动态开点线段树.最后再从根节点开始做一遍dfs,把每个节点对应的线段树启发式合并即可.时空复杂度均为O(nlog2n).听说还有一个log的做法,但感觉太神仙不会,不过2个log能过就不管了. #include<bits/stdc++.h> #define lson l,mid,tr[rt].lc #define rson mid+1,r,tr…