数据结构
&稚始稚终
这个作者很懒,什么都没留下…
展开
-
D. Ezzat and Grid (线段树维护dp)
D. Ezzat and Grid题目传送门:D. Ezzat and Grid题目大意:就是给你很多行的01串,长度是1e9,每一行都有若干段的连续的1,使得给定的串集合美丽的条件是任意相邻两行的串至少有一个列是同时有1的,问你至少删除多少行使得这些01串是美丽的,并输出删除的方案?思路:比较好想到的就是维护dp[i]表示以第i行为结尾时构成的最大集合,dp[i]可以被第j行更新(第i行和第j行有同列为1),然后取一个max即可。由于每一行的1都是连续的,与是需要执行的是区间加和区间最值查询的操原创 2021-08-11 17:25:55 · 360 阅读 · 2 评论 -
浅谈ST表
浅谈ST表先来一个小问题 :有N个数,M次询问,每次给定区间[L,R],求区间内的最大值。N<=10,M<=10老师,我会O(N)暴力枚举!再来:N<=10^ 5,M<=10^5老师,我会线段树O(logN)处理每个询问!再来:N<=10^ 5,M<=10^6这时候我们发现,随着M的增大,O(logN)的询问的处理已经不够优秀,我们需要O(1)处理询问的方法。这就引出我们今天的主题——ST表。算法流程:我们现在要O(1)求出区间最大值,转载 2021-05-26 22:00:14 · 151 阅读 · 0 评论 -
主席树详解
主席树详解要想学主席树,首先要搞懂可持久化线段树,因为主席树运用了它的思想。主席树的模板题是:静态查询区间第k小那么主席树的做法就是, 先把全部数字离散化,然后每一个前缀建一棵权值线段树,显然,如果直接建,那么空间上是不允许的,但是我们发现,每两个相邻的前缀中,只有一个数的差别,所以,他们的公共部分是很多的,所以我们就可以用可持久化线段树了!首先,要明确一下,主席树上每个结点的值的定义(我们设这个节点的管理范围为l~r,并且现在已经将这个数列离散化了):表示在当前前缀中,有多少个数的值在l ~ r中转载 2021-04-10 17:07:31 · 261 阅读 · 1 评论 -
String(线段树)
线段树求最长的相等字符串前缀题目:StringAC Code#include<bits/stdc++.h>using namespace std;const int N=1e5+10;char str1[N],str2[N];int a[N];struct node{ int l,r,lazy; int d[30];}tr[N*4];void pushup(int k){ for(int i=0;i<26;i++) tr[k]原创 2021-03-22 22:46:08 · 145 阅读 · 0 评论 -
multiset用法
C++语言中,multiset是 < set > 库中一个非常有用的类型,它可以看成一个序列,插入一个数,删除一个数都能够在O(logn)的时间内完成,而且他能时刻保证序列中的数是有序的,并且序列中可以存在重复的数简单的运用int main(){ //freopen("../in.txt","r",stdin); int x; scanf("%d",&x); multiset<int> h; while (x!=0) // 插入数转载 2021-03-09 20:01:59 · 332 阅读 · 0 评论 -
矩阵哈希
矩阵哈希解决的问题:给出一个大矩阵,再给出若干个小矩阵,问大矩阵中是否存在小矩阵。代码模板:#include<bits/stdc++.h>using namespace std;typedef long long ll;typedef unsigned long long ull;const int seed1=131,seed2=13331,maxn=1e5+10,mod=1e9+7;int n,m,t,x,y;char a[1004][1004];ull p1[max转载 2021-02-28 17:04:57 · 386 阅读 · 1 评论 -
哈希表创建的模板
创建哈希表#include<bits/stdc++.h>using namespace std;typedef long long LL;const LL maxn=1e7+10,mod=1e6+7;struct Hash{ int e,next,w;}edge[maxn];int head[maxn],cnt=0;void Init(){ memset(head,-1,sizeof(head)); cnt=0;}void Insert(LL x)原创 2021-02-28 15:54:14 · 90 阅读 · 0 评论 -
文艺平衡树算法
一、文艺平衡树解决什么问题您需要写一种数据结构,来维护一个有序序列。其中需要提供以下操作:翻转一个区间,例如原有序列是5 4 3 2 1,翻转区间是[2,4],结果为5 2 3 4 1二、文艺平衡树与普通平衡树a[5]={ 5 , 4 , 3 , 1 , 2 }那么存入文艺平衡树之后,再中序遍历的结果应该还是:{ 5 ,4 ,3,1,2}。即下标从小到大,而不是里面的值从小到大!这是与普通平衡树的最大的不同!文艺平衡树经过rotate旋转之后,它的中序遍历是不变的(即,下标从小到大)。但是让这颗树的原创 2021-02-17 16:30:42 · 2522 阅读 · 4 评论 -
Luogu P3871中位数 (splay求中位数)
AC Code#include<bits/stdc++.h>using namespace std;const int N=2e5+10;struct splay_tree{ int ff,cnt,ch[2],val,size;}tr[N];int root,tot;void update(int x){ tr[x].size=tr[tr[x].ch[0]].size+tr[tr[x].ch[1]].size+tr[x].cnt;}void rotate(.原创 2021-02-16 20:30:29 · 162 阅读 · 0 评论 -
Luogu P1503 鬼子进村(平衡树+栈)
思路:前面两个操作自然想到可以用栈模拟,然后可以把摧毁了的房子加到平衡树中。操作三的话只要找到前驱和后继即可,last-pre-1即为答案。AC Code#include<bits/stdc++.h>using namespace std;const int N=5e4+10;struct splay_tree{ int ff,ch[2],val,size;}tr[N];int root,tot;void update(int x){ tr[x].size.原创 2021-02-16 19:55:27 · 133 阅读 · 0 评论 -
Luogu P2234营业额统计(Splay模板题)
P2234 [HNOI2002]营业额统计AC Code#include<bits/stdc++.h>using namespace std;const int N=5e4+10;int root,tot;struct splay_tree{ int ff,cnt,ch[2],val,size;}tr[N];void update(int x){ tr[x].size=tr[tr[x].ch[0]].size+tr[tr[x].ch[1]].size+tr[原创 2021-02-09 21:03:02 · 210 阅读 · 0 评论 -
普通平衡树详解
Splay树首先介绍BST,也就是所有平衡树的开始,他的China名字是二叉查找树。BST性质简介给定一棵二叉树,每一个节点有一个权值,命名“关键码”,至于为什么叫这个名字,我也不知道。BST的性质就是,对于树中任何一个节点,都满足以下性质:1.这个节点的关键码不小于它的左子树上任意一个节点的关键码2.这个节点的关键码不大于它右子树上的任意一个关键码然后我们就可以发现这棵树的中序遍历,就是一个关键码单调递增的节点序列。Splay的背景什么是Splay,它就是一种可以旋转的平衡树。它可以解决转载 2021-02-09 19:53:52 · 799 阅读 · 0 评论 -
E.买礼物(线段树查询区间是否有重复的值)
买礼物题目传送门:买礼物思路:pre[i]表示第i个礼物的上一个相同礼物的位置nex[i]示第i个礼物的下一个相同礼物的位置我们要维护的就是区间 l ~ r 间nex[i]的最小值或者pre[i]的最大值。我这里维护的是pre[i]的最大值,当删除位置i的物品时,把pre[i]置成0,但需要注意的是因为删除了当前位置的礼物,所以我们还需要修改下一个位置的相同礼物的上一个位置,及 pre[ nex [i] ] = pre[i]。查询时看区间最大值是否大于等于r即可。AC Code#incl原创 2021-02-08 23:28:11 · 227 阅读 · 0 评论 -
手写带翻转标记的双端队列
带翻转标记的双端队列(听说双端队列用stl的话容易被卡常,还是记一下手写的比较好)const int MAXN=1e5+10;struct deQue{ int buffer[MAXN*2]; int head=MAXN,tail=MAXN-1; bool rev; //翻转标记 bool empty() { return tail<head; } int size() { return tai原创 2021-02-04 21:49:37 · 203 阅读 · 0 评论