
基础数据结构
文章平均质量分 51
基础
*DDL_GzmBlog
再见锋芒,准备启程
展开
-
*水题 [Luogu] P3420 [POI2005]SKA-Piggy Banks
前言因为 一不小心把init 写在了 cin>>n前面 导致debug半天 所以下次不分开写了 呜呜呜CODE#include <bits/stdc++.h>#define IOS ios::sync_with_stdio(false)using namespace std;typedef long long ll;const int N = 1e6+10;int p[N],n,m,st[N];int find(int x){ if(x!=p[x])原创 2021-06-20 20:39:18 · 134 阅读 · 0 评论 -
[Luogu] 并查集维护个数 P2078 朋友
文章目录题意步骤CODE(并查集 维护 集合元素个数 模板题)题意两个公司 (全是同性别的人)也就是一个公司 如果有男生 就不可能有 女生问你 在 小明(1代表) 和 小红 (-1代表 女生都用负数) 认识的人中最可能凑出来几对情侣(包括他们自己)吐槽本来以为是组合数问题 结果 画了一下关系图 就发现 凑出来的情侣数由 认识少的那一方 限制(那么问题 就简单了 )步骤这不就是 并查集 维护 集合中元素的个数 问题嘛那我们要怎么 维护 并查集集合中的 个数呢(其实很简单 我们原创 2021-06-20 16:41:31 · 217 阅读 · 0 评论 -
[Acwing] 142. 前缀统计 Tire_记录个数
前言传送门 :思路属于是 字典树 基础题,我们只需要在建树操作末尾的时候,记录一下个数即可然后查询的时候加上Mycode// Problem: 前缀统计// Contest: AcWing// URL: https://www.acwing.com/problem/content/144/// Memory Limit: 256 MB// Time Limit: 1000 ms// // Powered by CP Editor (https://cpeditor.org)#i原创 2022-04-16 16:49:14 · 230 阅读 · 0 评论 -
0x10 02 编辑器 双栈模拟
前言用栈模拟的一道题传送门 :思路我们可以利用两个栈来进行模拟 光标左右两边同时我们记录 左边的 最大MAXNMAXNMAXN 和 SUMSUMSUM如果是移动光标的操作的话,无非就是将一个栈的栈顶元素移动到另一个栈罢了CODE#include <bits/stdc++.h>using namespace std;#define ll long long#define endl '\n'const int N = 1e6+10;stack<int> l,原创 2021-10-24 22:31:58 · 125 阅读 · 0 评论 -
[Acwing] 128. 编辑器 栈模拟+最大值
前言hh,还是不够灵活传送门 :前言其实只要想想就会想到使用双栈 :分别为 : Left,RightLeft , RightLeft,Right 表示光标左右两边的值对于删除,移动光标等操作,无非就是对应了 pop(),push()pop(),push()pop(),push()从一个栈 到 另一个栈只不过这里有一个点,查询第kkk大的前缀和,给我难住了难道是优先队列来做 ??? ,如 : 此题型传送门想了想不该啊,显然瞄了一眼题解区,好家伙,直接在每次队左区间进行操作的时候,我们都进原创 2021-12-20 21:06:45 · 123 阅读 · 0 评论 -
[Acwing] 135. 最大子序和 滑动窗口
前言抽象出基础模型传送门 :思路不超过mmm的区间范围,求最大的sumsumsum显然我们可以统计前缀和这样子对于一个区间[L,R][L,R][L,R]的和就变成了sum[R]−sum[L]sum[R]-sum[L]sum[R]−sum[L]如果我们通过枚举 R(1−i)R(1-i)R(1−i) ,通过题意我们可知L∈[R−m,R−1]L \in [R-m,R-1]L∈[R−m,R−1]显然问题可以转换为,在一个大小为mmm的窗口内,找一个最小的sum[i]sum[i]sum[i]因此问原创 2021-12-22 12:54:35 · 336 阅读 · 0 评论 -
[Acwing] 150. 括号画家 用栈模拟+统计答案
前言传送门 :思路括号匹配 显然是 使用stackstackstack了,但是统计答案应该怎么统计呢 ?显然其中有一个非常直接的思路 对于每一次成功匹配我们就统计答案然后我们的stack<char>stack<char>stack<char> 转换为 stack<int>stack<int>stack<int>便于统计, 这样子我们只需要判断是否合法即可,如果不合法那么当前的栈头退出栈,否则将当前合法的位置加入队列中然后原创 2021-12-26 18:48:32 · 300 阅读 · 0 评论 -
[Acwing] 154. 滑动窗口 单调队列
前言hh总算是理解了传送门 :思路朴素算法的分析 :显然我们可以对于每一个区间都进行一遍找最大最小值,时间复杂度O(n∗k)O(n*k)O(n∗k),在kkk大的情况下,显然是会TLETLETLE的,而且我们也不难发现,对于除了开头k−1k-1k−1和结尾k−1k-1k−1个数之外,其他数都进行了kkk次 比较这里我们可以采用单调队列优化 :队列的性质 : 后进先出对于入队操作,我们考虑 :如果当前一个数需要进入队列内,若这个数比先进队的数大 , 那么显然 前面的数不可能是我们需要统原创 2021-12-19 18:34:52 · 297 阅读 · 1 评论 -
[Acwing] 150. 括号画家
前言心态爆题Codeblocks导致电脑宕机超出String读入传送门 :思路因为要求的是连续子串对于每一次匹配我们就统计一次答案如果不匹配那么就将当前的节点加入栈中Mycodetypedef priority_queue<int,vector<int>,greater<int>> Pri_m;typedef pair<int,int> pii;typedef pair<char,int> pci;typedef原创 2022-03-14 22:33:56 · 250 阅读 · 0 评论 -
[luogu] P1168中位数 vector||堆||树状数组
文章目录前言VectorCODEHeapCODE前言传送门 :题解千奇百怪Vector因为我们是需要输出 一个序列里面有序的中位数,显然我们不可能每次插入都进行一次排序所以我们可以利用二分,索引下标之后再进行查找CODE#include <bits/stdc++.h>using namespace std;#define ll long long#define endl '\n'const int N = 10;void cal(){}void solve(原创 2021-10-21 10:56:04 · 164 阅读 · 0 评论 -
[abc] F - Confluence 并查集 按秩合并
前言传送门 : https://atcoder.jp/contests/abc183/tasks/abc183_f思路本题需要求的是将两个 x 和 y 合并到一个集合中将 计算 在x所属集合中 和 y 同一个班级的个数第一个 : 不就是裸并查集吗第二个 : 一开始以为只是简单的 维护 集合内的个数但是没想到还给集合分了类,因此我们一开始想到的是二维数组(二维数组给每一个类都记一下 )但是呢 这题数据不好开 所以我们可以 用map来处理这样子我们就不用每个集合都开了 ,我们只需要维护原创 2021-10-04 14:20:53 · 157 阅读 · 0 评论 -
[luogu] P4981 父子 Cayley定理
前言https://www.luogu.com.cn/problem/P4981我是来做最小生成树的QAQ(怎么下一题又是Cayley定理)思路看完题目不难发现就是让我们求 n个节点的有根树 有多少个形态已知Cayley定理是求无根树所以对于每一个无根树 我们都有n种选根 方案所以这题的公式就是:nn−1 mod 1e9+9n^{n-1} \bmod 1e9+9nn−1mod1e9+9因为有t组 选择用qmiCODE#include <bits/stdc++.h>usi原创 2021-09-24 15:14:52 · 160 阅读 · 0 评论 -
[luogu]P4430 小猴打架 生成树Cayley定理
目录前言思路CODE前言https://www.luogu.com.cn/problem/P4430树的尽头便是数论吗(QAQ)思路前置技能:Cayley定理:不同的n节点带标号生成无根树的数量为 nn−2n^{n-2}nn−2又因为题中不考虑前后顺序(也就是排列)对于生成的树有(n-1)条边,所以 这题的公式如下:(n−1)!∗nn−2 mod 9999991(n-1) ! * n^{n-2} \bmod 9999991(n−1)!∗nn−2mod9999991CODE#inclu原创 2021-09-24 15:03:13 · 338 阅读 · 0 评论 -
[算法总结] LCA倍增法 dfs
https://www.luogu.com.cn/problem/P3379#include <bits/stdc++.h>using namespace std;const int MAXN = 500010;const int DEG = 20;struct Edge{ int to,next;} edge[MAXN*2];int head[MAXN],tot;void addedge(int u,int v){ edge[tot].to = v;原创 2021-04-24 17:19:02 · 206 阅读 · 0 评论 -
[ 补题|题解 ] A - The Child and Sequence
目录前言题目CODE前言题目链接 :VJ: https://vjudge.net/contest/446835#problem/ACF: https://codeforces.com/problemset/problem/438/D?mobile=true做这题的时候 感觉挺简单, 最后debug了2小时 真心不容易QAQ (还是太菜了)难度: 线段树入门基础题题目(题目就这么简单 不信你自己看)三个操作:区间求和区间取模单点修改区间求和,和单点修改都是线段树基本操作但是原创 2021-09-15 14:34:42 · 162 阅读 · 0 评论 -
[洛谷] P3374 【模板】树状数组 1
[传送门]问题:树状数组: 单点修改,区间查询感觉还是挺简单的嘛 就一个lowbitCODE#include <bits/stdc++.h>using namespace std;const int N = 5e5+10;typedef long long ll;ll a[N],c[N];ll n,m;ll lowbit(ll x){ return x&(-x);}void updata(ll i,ll k){ while(i<原创 2021-06-15 16:01:17 · 118 阅读 · 0 评论 -
[nk] I-完美主义 树状数组
前言传送门:思路将关系a[i]<=a[i−1]a[i]<=a[i-1]a[i]<=a[i−1]转换成1 | 0 然后通过前缀和记录当我们需要修改的时候,我们只需要枚举四个状态然后分别对应modify即可具体看代码CODEint lowbit(int x){ return x &(-x);}void modify(int k,int x){ for(int i = k;i<=n;i+=lowbit(i)) b[i]+=x;}int query原创 2021-11-13 22:36:09 · 250 阅读 · 0 评论 -
[Luogu] *P4868 Preprefix sum 树状数组
前言传送门 :这个修改什么鬼啊思路大概这样没看懂修改CODE#include <bits/stdc++.h>using namespace std;#define int long long#define ll long long#define endl '\n'const int N = 1e5+10;int ans,len;int a[N],trA[N<<1],trB[N<<1];int lowbit(int x){ ret原创 2021-10-21 15:52:32 · 122 阅读 · 0 评论 -
[洛谷] P3368 【模板】树状数组 2
[传送门]问题区间更新 单点查询解决用差分数组来处理注意: getsum(i) 就已经是当前点的值了CODE:#include <bits/stdc++.h>using namespace std;const int N = 5e5+10;typedef long long ll;ll a[N],c[N];ll n,m;ll lowbit(ll x){ return x&(-x);}void updata(ll i,ll k){ wh原创 2021-06-15 16:09:42 · 105 阅读 · 0 评论 -
[luogu] P1637 三元上升子序列 树状数组
前言真简单,数据结构真简单!!传送门 :思路计算一个 三元上升序列 我们可以枚举 中间节点 然后通过乘法原理 记录Left[]和Right[]Left[] 和 Right[]Left[]和Right[]当然数据范围是3e5+10 如果直接求会爆炸 所以我们还需要离散化因为我们只需要 离散化 并且 枚举中间节点求出所有的Left[i]∗Right[i]Left[i]*Right[i]Left[i]∗Right[i]之和即是答案CODE#include <bits/stdc++.h>原创 2021-10-20 14:52:20 · 192 阅读 · 0 评论 -
[Acwing] 区间最大公约数 线段树
前言传送门:总体思路很流畅,就是代码不怎么好写思路题目要求两个操作 :区间更新 : 懒标记 (难写啊!区间查询 : 查询gcdgcdgcd更不好写!区间更新的优化 :区间+++ 或者 −-− 一个数 可以用 差分 变成单点操作区间查询优化 :根据 gcd(a,b)=gcd(a,b−a).....gcd(a,b,c,d...)=gcd(a,b−a,c−b,...)gcd(a,b) = gcd(a,b-a)..... gcd(a,b,c,d...) = gcd(a,b-a,c-b,原创 2021-10-18 18:28:53 · 147 阅读 · 0 评论 -
[Acwing] 143. 最大异或对 Tire树
前言一看就是Tire树 一做就不会思路常规暴力解法:O n2n^2n2 枚举出 所有选法取最大即可使用Tire树优化第二层循环:Onlognnlognnlogn , 使用Tire存放每个数的 二进制数 即 Tire[N∗31][2]Tire[N*31][2]Tire[N∗31][2]然后我们在枚举每一个a[i]a[i]a[i]的时候,如果 a[i]a[i]a[i]是1 那么我们就走 0反之则然因此这样子就保证了对于每个a[i]a[i]a[i]我们都可以取得最大值CODE#incl原创 2021-10-12 11:07:16 · 139 阅读 · 0 评论 -
[算法总结] 平衡树 !
平衡树种类set,map(红黑树的变种)treap( Tree + heap -二叉搜索树+堆-)二叉搜索树(BST)TreapNode : code左旋右旋(所有的平衡树都有)Splay(竞赛用的非常多的一个平横树)sbt(暂时不了解)AVL(暂时不了解)红黑树(工程用 - 不做了解)种类set,map(红黑树的变种)treap( Tree + heap -二叉搜索树+堆-)二叉搜索树(BST)什么是二叉搜索树每个结点都有一个权值,当前结点的左子树中任何一个点的权值都严格小于当前结点的权原创 2021-05-16 14:44:16 · 362 阅读 · 0 评论 -
[算法总结] 单调栈
单调栈定义例题分析:Acwing 830. 单调栈思路分析code:定义顾名思义,单调栈即满足单调性的栈结构。例题分析:Acwing 830. 单调栈-------------------传送门--------------------------思路分析我们可以通过栈来存放比当前数小的数(才发现还挺难 没讲明白)code:#include <bits/stdc++.h>using namespace std;int main(){ int n ;原创 2021-05-25 23:40:44 · 181 阅读 · 1 评论 -
[luogu] P2709 小B的询问 莫队初步
前言传送门: https://www.luogu.com.cn/problem/P2709思想暴力做法 对于每一个询问 我们都 for 一次 那么 最终复杂度是 O(nm)的但是如果 我们用离线的方法 进行操作的话 那么可以降到 O n√NQ :如何操作呢?A :对访问的数组进行排序用双指针进行移动区间这么一看 我们明面上是优化了 询问的 操作但是因为双指针的存在 如果 询问不是O(1)的 那么时间复杂度爆炸CODE#include <bits/stdc++.h>u原创 2021-10-01 22:12:48 · 121 阅读 · 0 评论 -
[Awing]维护序列 线段树,区间操作
前言传送门 :好久没写,线段树了,没想到被难到了思路区间操作 对应 懒标记两个区间操作 即 两个懒标记Q: 两个懒标记应该先计算哪个 ?如果先计算加法再计算乘法,那么加法一定需要被乘数整除才行因此先使用加法对于每个数我们都看成 a∗b+ca*b+ca∗b+c因此对于 乘法懒标记 我们可以b∗mulb*mulb∗mul对于加法懒标记c∗mul+addc*mul + addc∗mul+add然后就是不好写 QAQCODE#include <bits/stdc++.h&原创 2021-10-19 11:14:56 · 144 阅读 · 0 评论 -
[abc] E - LEQ 树状数组+组合计数
前言真简单,树状数组真简单,数论真简单 (我在口胡)传送门 : https://atcoder.jp/contests/abc221/tasks/abc221_e补题借鉴 : https://zhuanlan.zhihu.com/p/416410911思路题目需要求的是 满足 所有组数A1′≤Ak′A_{1}^{\prime} \leq A_{k}^{\prime}A1′≤Ak′因此不难想象 如果我们排序之后 那么我们只需要枚举k对于每一个k我们都求出所有可能 即 2k2^{k}2k (原创 2021-10-04 10:46:37 · 197 阅读 · 0 评论 -
[Acwing] Trie字符串统计
目录前言做法CODE:前言刚刚 2分钟 没写出来 又不熟练了所以记录一下做法通过 son[N][26] 建立一颗树 通过cnt[N] 记录 以当前结尾的串个数 通过idx来区别其他串基本操作步骤就是for(int i = 0 ; i<len; i++){ int u = s[i]-'a'; if(!son[p][u]) { son[p][u] = ++idx; } p=son[p][u];}cnt[p] ++原创 2021-06-21 16:49:12 · 158 阅读 · 0 评论 -
[算法总结] 线段树(不会详讲)!
线段树1.树的信息2.针对单点操作-pushup操作(通过子节点信息来计算父节点)-建树操作-查询操作-单点更新3.针对区间的操作-关于lazy标记-pushup(更新父节点操作没变)-建树操作(也没变)-PushDown操作-查询操作(多了一个pushdown操作)-更新操作(区间更新)以上两个模板1.单点区间求最大2.求区间和本篇线段树分析的是Acwing上的线段树代码1.树的信息这里注意 , 请开4倍空间 , 无证明这里用结点存储区间 少了在函数那里的形参 (yxc yyds!)stru原创 2021-04-30 16:02:06 · 303 阅读 · 1 评论 -
[Acwing|蓝桥] AcWing 1242. 修改数组 并查集 + 思路
前言传送门 :思路这题使用并查集 处理太巧妙了利用并查集集合的性质 , 首先解决了 是否在集合中的问题同时还利用p[x]=x+1p[x] = x+1p[x]=x+1,解决了连续性的问题MyCodeint p[N],n;int find(int x){ if(x!=p[x]) return p[x] =find(p[x]); return p[x];}void solve(){ for(int i=1;i<=N;i++) p[i]=i; cin>&原创 2022-03-10 22:24:38 · 154 阅读 · 0 评论 -
[算法总结] 树状数组(不会详讲)!
目录前言树状数组(单点更新,区间查询)建树操作求和操作main函数(区间更新,单点查询)问题描述解决方法建树操作(没变)求和操作(没变)main函数(区间更新,区间查询)问题描述解决方法建树操作求和操作main函数前言本来以为线段树可以实现所有树状数组的题,结果某一天我就被制裁了所以我就滚回来归纳一下树状数组了,以免下次再次sb\树状数组(单点更新,区间查询)建树操作A[i] 包含于 C[i + 2k]、C[(i + 2k) + 2k]…;k为i的二进制中从最低位到高位连续零的长度原创 2021-05-03 20:52:04 · 383 阅读 · 1 评论 -
[luogu] P1396 营救 二分答案+并查集
前言二分答案 可真难啊。。传送门 :思路我们可以通过边权的最大值和最小值进行二分答案然后对于每一个答案 我们都通过并查集判断是否可以到达CODE#include <bits/stdc++.h>using namespace std;#define ll long long#define endl '\n'const int N = 1e5+10;const int INF = 0x3f3f3f3f3f;int n,m,s,t,ans;int a[N],b[N],vi原创 2021-10-24 16:11:04 · 180 阅读 · 0 评论