cstring

线段树合并&&启发式合并笔记

本小妞迷上赌 提交于 2020-04-30 04:15:30
这俩东西听起来很高端,实际上很好写,应用也很多~ 线段树合并 线段树合并,顾名思义,就是建立一棵新的线段树保存原有的两颗线段树的信息。 考虑如何合并,对于一个结点,如果两颗线段树都有此位置的结点,则直接合并两结点的信息(如维护最大值则取max,维护和则相加),然后递归处理左右子树; 若只有一个有,直接返回即可。 这样子做时间复杂度取决于重合节点个数,一次最坏复杂度是$O(nlogn)$,因为满二叉树的结点数是$O(n)$,对每个结点进行处理是$O(logn)$,但是实际应用中需要合并的两颗树重合部分一般较少,所以复杂度可以近似看为$O(logn)$的; 如果用动态开点线段树的话,一次合并只需要合并一条链,所以时间复杂度是$O(操作数\times logn)$的 启发式合并 启发式合并核心思想就一句话:把小集合的合并到大的里。 启发式合并思想可以放到很多数据结构里,链表、线段树、甚至平衡树都可以。 考虑时间复杂度,设总共有$n$个元素,由于每次集合的大小至少翻倍,所以至多会合并$logn$次,总的复杂度就是$O(nlogn)$的(结合线段树合并就是$O(nlog^2n)$的) 下面举几道例题: 【BZOJ1483】【HNOI2009】梦幻布丁 链表+启发式合并,每次换颜色直接合并 1 #include<iostream> 2 #include<cstring> 3 #include

POJ-2528 Mayor's posters (线段树+离散化)

北城余情 提交于 2020-04-30 03:18:03
The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their electoral posters at all places at their whim. The city council has finally decided to build an electoral wall for placing the posters and introduce the following rules: Every candidate can place exactly one poster on the wall. All posters are of the same height equal to the height of the wall; the width of a poster can be any integer number of bytes (byte is the unit of length in Bytetown). The wall is divided into segments and the width of each segment is one byte. Each

HDU1199 动态线段树 // 离散化

我与影子孤独终老i 提交于 2020-04-30 03:17:03
附动态线段树AC代码 http://acm.hdu.edu.cn/showproblem.php?pid=1199 因为昨天做了一道动态线段树的缘故,今天遇到了这题没有限制范围的题就自然而然想到了动态线段树的解法,写完看题解发现原来只要离散化就好了(干。。),总结了一下这题和昨天hdu5367的区别在于,虽然都是两题范围超级大的线段树,但是昨天的强制要求在线求解,只能选择空间复杂度更大一些的动态线段树来求解,而今天的这题可以选择离线操作,因而可以采用先读入所有输入,离散化之后建树的方法来操作。下次遇到这样的题还是应当优先考虑离散化。 在一个全部涂黑色的条子上涂上一些白色或黑色的片段,问最大白色片段。 仅仅从线段树维护节点的角度上来看很简单,维护最大白色片段,左边最大白色片段,右边最大白色片段就好了。 由于条子的长度长达1-INT_MAX; 采用离散化,或者像我一样失了智去用动态线段树的方法,也能AC #include <map> #include < set > #include <cmath> #include <queue> #include <stack> #include <vector> #include < string > #include <cstdio> #include <cstdlib> #include <cstring> #include <sstream

可持久化线段树+主席树+动态主席树

北慕城南 提交于 2020-04-30 03:13:42
可持久化线段树 整体还是很容易理解的,网上的教程都挺不错,所以只简单介绍下 可持久化的原理在于, 借用已经建过的线段树的一部分 比如,我们有一个数列$a=\{12,23,34,45,56,67,78,89\}$ 而我们想要带修改的维护这个数列中$[L,R]$的区间和 建一颗正常的、维护$a_1$~$a_8$区间和的线段树就能解决了,这样就是不修改的情况 问题在于,如果想在这个的基础上 维护历史版本 ,应当如何处理? 假设第一次修改,将$a_3$改为$90$ 如果我们据此重新建立一颗线段树,可以发现,只有很少的节点跟初始的线段树有出入 如果说的更加确切,有出入的节点为 被修改点及其所有祖先 所以,我们建立一颗新的线段树,相当于 向某个历史版本插入一条长度为logN的链 而对于这条链,每个节点的一个儿子一定指向一个没有出入的区间(即之前某个历史版本的节点)、另一个一定指向一个包含点修改的区间(新创建的节点),分开操作一下就行了 这样,$M$次操作时,整体的时空消耗是$O(N+MlogN)$ 模板题: 洛谷P3919 虽然是可持久化数组,但是稍微修改一下(把修改和查询换成区间)就是可持久化线段树了 (注释的是自己一开始犯的两个错误) #include <cstdio> #include <cstring> #include <cmath> #include <iostream>

[线段树-模板] 线段树+离散化

允我心安 提交于 2020-04-30 02:36:23
输入 每个测试点(输入文件)有且仅有一组测试数据。 每组测试数据的第1行为两个整数N和L,分别表示总共贴上的海报数量和宣传栏的宽度。 每组测试数据的第2-N+1行,按照贴上去的先后顺序,每行描述一张海报,其中第i+1行为两个整数a_i, b_i,表示第i张海报所贴的区间为[a_i, b_i]。 对于100%的数据,满足N<=10^5,L<=10^9,0<=a_i&ltb_i<=L。 输出 对于每组测试数据,输出一个整数Ans,表示总共有多少张海报能被看到。 #include <iostream> #include <cstring> #include <vector> #include <algorithm> using namespace std; struct node{ int flag; // 海报编号 int l,r; // 左端点,右端点 }; vector < int > v; // 用于离散化 int pt_x[ 100005 ],pt_y[ 100005 ]; // 记录区间端点 node tree[ 100000 * 40 ]; // 线段树 bool use[ 100005 * 2 + 10 ]; // 记录能看到的海报 int ans; // 能看到的海报数 // 获得离散值 int getID( int x){ return lower_bound(v

BZOJ5168:[HAOI2014]贴海报(线段树)

守給你的承諾、 提交于 2020-04-30 00:32:46
Description Bytetown城市要进行市长竞选,所有的选民可以畅所欲言地对竞选市长的候选人发表言论。为了统一管理,城市委 员 会为选民准备了一个张贴海报的electoral墙。张贴规则如下: 1.electoral墙是一个长度为N个单位的长方形,每个单位记为一个格子; 2.所有张贴的海报的高度必须与electoral墙的高度一致的; 3.每张海报以“A B”表示,即从第A个格子到第B个格子张贴海报; 4.后贴的海报可以覆盖前面已贴的海报或部分海报。 现在请你判断,张贴完所有海报后,在electoral墙上还可以看见多少张海报。 Input 第一行: N M 分别表示electoral墙的长度和海报个数 接下来M行: Ai Bi 表示每张海报张贴的位置 Output 输出贴完所有海报后,在electoral墙上还可以看见的海报数。 1 0<= N <= 10000000 1<=M<=1000 1<= Ai <= Bi <=10000000 所有的数据都是整数。数据之间有一个空格 Sample Input 100 5 1 4 2 6 8 10 3 4 7 10 Sample Output 4 Solution 裸的线段树区间覆盖的题目,覆盖一下最后统计一波就好了 Code 1 #include<iostream> 2 #include<cstring> 3 #include

P2339 提交作业usaco

半腔热情 提交于 2020-04-29 20:38:48
P2339 提交作业usaco 题目背景 usaco 题目描述 贝西在哞哞大学选修了 C 门课,她要把所有作业分别交给每门课的老师,然后去车站和同学们一起回家。每个老师在各自的办公室里,办公室要等他们下课后才开,第 i 门课的办公室将在 Ti 分钟后开放。 所有的办公室都在一条笔直的走廊上,这条走廊长 H 个单位,一开始贝西在走廊的尽头一侧,位于坐标为 0 的地方。第 i 门课的办公室坐标位于坐标为 Xi 的地方,车站的坐标为 B。贝西可在走廊上自由行走,每分钟可以向右或者向左移动一个单位,也可以选择停着不移动。如果走到一间已经开门的办公室,贝西就可以把相应的作业交掉了,走进办公室交作业是不计时间的。请帮助贝西计算一下,从她开始交作业开始,直到到交完所有作业,再走到车站,最短需要多少时间时间。 输入输出格式 输入格式: 输入格式 • 第一行:三个整数 C, H 和 B, 1 ≤ C ≤ 1000 , 1 ≤ H ≤ 1000 , 0 ≤ B ≤ H • 第二行到 C + 1 行:第 i + 1 行有两个整数 Xi 和 Ti, 0 ≤ Xi ≤ H , 0 ≤ Ti ≤ 10000 输出格式: 输出格式 • 单个整数,表示贝西交完作业后走到车站的最短时间 输入输出样例 输入样例#1: 4 10 3 8 9 4 21 3 16 8 12 输出样例#1: 22 说明 走到坐标 8 处,第

OpenCV积分图函数:integral ()详解

隐身守侯 提交于 2020-04-29 10:09:04
/**************************************************************************************************/ // 函数名称:OnMenu020503() // 函数功能:“对角积分图”菜单。 // 函数参数: // 输入参数: 无 // 输出参数: 无 // 返 回 值:void // 创建作者:(QQ:370711753) // 修改日期:2017/11/08 16:25:58 /**************************************************************************************************/ void COpenCVDlg::OnMenu020503() { try // 错误处理 { Mat lv_MatImageIntegralSum = Mat(); Mat lv_MatImageIntegralSqSum = Mat(); Mat lv_MatImageIntegralTilted = Mat(); Mat lv_MatImageIntegralNorm = Mat(); // 计算积分图像 cv::integral(m_MatImageRead, lv_MatImageIntegralSum,

VC++下处理UTF8编码的字符串

*爱你&永不变心* 提交于 2020-04-28 18:59:25
void UTF8toANSI(CString &strUTF8) { //获取转换为多字节后需要的缓冲区大小,创建多字节缓冲区 UINT nLen = MultiByteToWideChar(CP_UTF8,NULL,strUTF8,-1,NULL,NULL); WCHAR *wszBuffer = new WCHAR[nLen+1]; nLen = MultiByteToWideChar(CP_UTF8,NULL,strUTF8,-1,wszBuffer,nLen); wszBuffer[nLen] = 0; nLen = WideCharToMultiByte(936,NULL,wszBuffer,-1,NULL,NULL,NULL,NULL); CHAR *szBuffer = new CHAR[nLen+1]; nLen = WideCharToMultiByte(936,NULL,wszBuffer,-1,szBuffer,nLen,NULL,NULL); szBuffer[nLen] = 0; strUTF8 = szBuffer; //清理内存 delete []szBuffer; delete []wszBuffer; } //ANSI转UTF8 void ANSItoUTF8(CString &strAnsi) { //获取转换为宽字节后需要的缓冲区大小

CF1342C Yet Another Counting Problem

笑着哭i 提交于 2020-04-28 18:44:52
Yet Another Counting Problem 思路:假设a <= b。 x % a % b = x % a是显然成立的,那么只需要比较 x % a != x % b % a的情况就可。 通过手写 x % a 和 x % b % a的情况,发现我们只需要写出一个lcm(a,b)的表格(lcm最小公倍数),就是一个循环表, 有了循环表,我们只需要统计一个循环表中每个位置不同余数的个数就可以,我们就可以处理1e18的数据了。 1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <functional> 5 #include < set > 6 #include <vector> 7 #include <queue> 8 #include <cstring> 9 10 11 using namespace std; 12 13 #define ll long long 14 #define pb push_back 15 #define fi first 16 #define se second 17 18 const int N = 1010 ; 19 const int INF = 1e9; 20 21 int gcd( int a, int b){ 22 return b