进阶算法
进阶算法。。。
东篱下の悠然
有一分热,发一分光,就令萤火一般,也可以在黑暗里发光,不必等候炬火~
展开
-
【专栏置顶】本专栏思维导图(目录)
“进阶算法”专栏,思维导图,阅读导图原创 2021-01-06 14:22:16 · 400 阅读 · 0 评论 -
树状数组
vijos 1512 SuperBrother打鼹鼠#include <bits/stdc++.h>using namespace std;const int maxn = 1050;int c[maxn][maxn], n;inline int lowbit(int x) { return x & (-x);}void add(int x, int y, int k) { while (y <= n) { c[x][y] +=原创 2021-01-23 18:26:22 · 81 阅读 · 0 评论 -
树状数组
vijos 1066 弱弱的战壕#include<bits/stdc++.h>using namespace std;const int N=15005;int tree[32010];//树状数组int ans[N];//答案int lowbit(int k){ //找到对应低一级数段 求lowbit的值 lowbit:二进制数k最低位1的十进制,计算c[t]展开的项数 return k & -k;}int sum(int k){ //查询区间和原创 2021-01-22 16:20:01 · 77 阅读 · 0 评论 -
树状数组(BIT)(学习)
解决问题:区间求和,端点修改“进阶算法”专栏(目录)原创 2021-01-14 14:54:07 · 81 阅读 · 0 评论 -
并查集
银河英雄传说 洛谷1196题意:有30000个节点,每次给出操作或询问,操作是将某两个节点所在链连接起来,询问是查询两个节点是否在同一个链中,两个链之间间隔了多少节点思路:带权并查集,边权存储这个节点到根节点的节点数,最前端的节点记录这条链上一共有多少节点,路径压缩按照并查集方式处理即可,合并集合既要权值合并,也要更新顶部节点存的节点数,用于计算合并时的边权。#include <bits/stdc++.h>using namespace std;int fa[30010], va原创 2021-01-12 19:45:30 · 99 阅读 · 0 评论 -
并查集
How Many Answers Are Wrong题目大意:有一个数列长度为n,给出m个描述,每个表述给出一个区间和区间上的和,求这m个描述中有多少个和前面的是冲突的解题思路:我们不知道数列的具体内容,只知道若干区间和是多少,然而如果区间和是相邻的,则可以组合成一个更大的区间,也就是通过已有区间推理出更多区间和。使用带权并查集,每一个节点表示一个区间的起点,它的父亲节点表示这个左闭右开区间的右端点,边上的权值就是这个区间上的和,对于给出的每一个描述先判断是否联通,如果联通就判断权值是否吻合,如果原创 2021-01-12 14:48:30 · 68 阅读 · 0 评论 -
并查集
洛谷2661 信息传递思路:每个人一开始只知道自己的生日——并查集初始化对于每个人,如果他不在集合里(父节点仍然是自己),就加入集合(把父节点改为给自己传话的人);如果它构成环,则维护最小环#include <bits/stdc++.h>using namespace std;int fa[200005];int tans, ans = 1e9;int Find(int x) { tans++; if(fa[x] == x) { return原创 2021-01-10 18:01:18 · 55 阅读 · 0 评论 -
并查集
https://vijos.org/p/1776 关押罪犯思路:初始化两倍大并查集,将怨气值关系存入结构体数组中,按照怨气值大小进行排序,从高到低遍历,遇到根节点相同(在同一监狱)就找到,直接输出;否则将他们分入不同监狱(彼此的补集相连接)#include <algorithm>#include <cstdio>using namespace std;int f[40004];struct held { int a, b, y;} cri[100001];原创 2021-01-10 15:01:45 · 64 阅读 · 0 评论 -
并查集
洛谷2024 食物链思路:首先时是三类动物——不能使用二分图染色。可以用拆点并查集和种类并查集。种类并查集代码:#include <bits/stdc++.h>using namespace std;const int maxN = 100005;int n, m, ans, fa[maxN * 3];int find(int u) { //找祖先 return fa[u] == u ? u : fa[u] = find(fa[u]); }int main() {原创 2021-01-10 13:07:59 · 112 阅读 · 2 评论 -
并查集
vijos1034 家族合并集合,查询两个人是否在同一个集合中#include <bits/stdc++.h>using namespace std;int fa[5005];int find(int x) { //寻找父亲节点的id号 return fa[x] == x ? x : fa[x] = find(fa[x]); }int main() { int n, m, p; cin >> n >> m原创 2021-01-09 22:44:53 · 66 阅读 · 0 评论 -
并查集
poj2492 A Bug’s Life题目大意:输入互相交配的两只虫,检查是否存在同性恋情况…对于此题,二分图染色较为局限不适用此题,拆点并查集要创建相对立的节点不适合此题,此题适合用种类并查集解题思路:将发生关系的两只虫聚合——能连接在一起的就不是一个性别的虫对于两只虫,比较一下看发生过关系没,有同一个根节点就代表之前发生了关系,根节点不同就是之前没发生过关系;再看看这两只虫的性别,如果这两只虫发生过关系并且性别相同,即导出矛盾。#include <bits/stdc++.h>原创 2021-01-09 18:27:19 · 66 阅读 · 0 评论 -
并查集(学习)
并查集是一种数据结构,可以快速合并多个集合,查询元素是否在相同集合中操作一,初始化并查集,就是将各个节点的父亲节点初始化为自己:for (int i = 1; i <= n; i ++) { father[i] = i;}操作二,给出元素x,询问这个元素所在树的根节点:int root(int x) { if(x == father[x]) { return x; } else { return root(father[x])原创 2021-01-08 21:27:16 · 135 阅读 · 0 评论 -
数据结构综合应用——堆
小复习:哈夫曼树的构造方法,每次找到权值最大的两个节点,合并,删掉,加入树,即堆的典型应用,用堆实现贪心的过程洛谷2168题意:将单词按照出现次数重新编码,使新编排的史诗实现哈夫曼树思路:K叉哈夫曼树每次找到最小的k个节点,合并成一个节点,加入堆中有可能使得根节点处不满造成根节点处浪费,要先补充几个权值为0的节点当一个k叉树有m个中间节点,则有m(k - 1) + 1个叶子节点,所以补充n / (k + 1)余数为1个节点即可#include <bits/stdc++.h>usi原创 2021-01-08 19:07:16 · 88 阅读 · 0 评论 -
数据结构综合应用——堆
学习:priority_queue 基础类型默认是大根堆,全的写法是priority_queue <int,vector,less >洛谷:2827题意过程描述:(变量sig记录经过时间增加的长度)找到最值切成两半插入新产生的两个值sig记录增加的长度80分代码:#include <bits/stdc++.h>using namespace std;priority_queue <int> ans; //大根堆int n, m, q, u,原创 2021-01-06 22:52:25 · 90 阅读 · 0 评论 -
数据结构综合应用——堆
洛谷1631题意:给两个有序序列a, b,大小都是N,在每个序列中各取一个数相加,则有N^2个数,输出最小的前N个数思路:无论如何,a序列的第一位数一定要用到,先将这个数和b中每一个数相加,标记,并扔进大根堆中排序,每次输出一个最小值,追溯这个值来源的下标,并根据下标插入新的值*其中a[t[m]] + b[m],t[m]所存的的值表示a序列加到哪一位数了,m表示b序列加到哪一位数了#include<bits/stdc++.h>using namespace std;int a[1原创 2021-01-06 18:15:22 · 104 阅读 · 0 评论 -
数据结构综合应用——堆
动态维护中位数问题,可以用堆,树状数组,线段树等数据结构解决堆,可以用来进行插入,查询最值,删除最值等操作解题思路:构建一大根堆和一小根堆,大根堆维护最小值,小根堆维护最大值。控制小根堆的大小,当是奇数个数时候...原创 2021-01-05 23:14:47 · 177 阅读 · 0 评论