数据结构
行走天涯的豆沙包
人生天地间,忽如远行客。
展开
-
BF的数据结构题单-提高组——P2680 运输计划
题解:题目让我们找一条边变成0,然后让整个运输航线的距离总和最短。也就是最大的最短,所以可以用二分。然后我们可以知道这个边一定在最长的那条链上面所以在树上差分找到经过次数最多的那条链。#include <bits/stdc++.h>using namespace std;typedef long long ll;inline int read(){ int p=0,f=1;char c=getchar(); while(c<'0'||c>'9'){if(c原创 2020-11-15 16:35:03 · 170 阅读 · 0 评论 -
BF的数据结构题单-提高组——P2590 [ZJOI2008]树的统计
没啥好说的,还是板题。#include<bits/stdc++.h>using namespace std;#define ls rt<<1#define rs rt<<1|1const int N=3e4+10;int head[N],e[N<<1],nw[N],ne[N<<1],w[N],cnt,n;struct Segment_Tree{ static const int maxn = 1e5 + 5; stru原创 2020-11-14 16:21:15 · 152 阅读 · 0 评论 -
BF的数据结构题单-提高组——树链剖分
树链剖分板子题#include <bits/stdc++.h>using namespace std;#define ll long long#define ls 2 * rt#define rs 2 * rt + 1#define N 100005int n, m; vector<int> edge[N];int id[N], nw[N], w[N], tot;int dep[N], sz[N], top[N], fa[N], son[N],r,mod;inli原创 2020-11-14 00:52:38 · 794 阅读 · 0 评论 -
BF的数据结构题单-提高组——P1783 海滩防御
题解:二分+并查集超时了,然后想了下可以用生成树来做,答案一定是每个点的左右距离和两两距离和之内产生。#include<bits/stdc++.h>using namespace std;const int N=1e5+10;const double esp=1e-3;int n,m,pre[N];typedef pair<int, int> pp;map<pp,int> mp;vector<pp> g;struct Node{原创 2020-11-12 12:36:10 · 187 阅读 · 0 评论 -
BF的数据结构题单-提高组 ——P1197 [JSOI2008]星球大战
P1197 [JSOI2008]星球大战题解:经典题,反向加边。#include<bits/stdc++.h>using namespace std;const int N=4e5+10;vector<int> g[N];int pre[N];typedef pair<int,int> pp;vector<pp> edge;int res[N],cnt,vis[N],a[N];int find(int a){ if(pre[a]原创 2020-11-11 23:48:53 · 185 阅读 · 0 评论 -
树套树——线段树套set
请你写出一种数据结构,来维护一个长度为 n 的序列,其中需要提供以下操作:1 pos x,将 pos 位置的数修改为 x。2 l r x,查询整数 x 在区间 [l,r] 内的前驱(前驱定义为小于 x,且最大的数)。数列中的位置从左到右依次标号为 1∼n。区间 [l,r] 表示从位置 l 到位置 r 之间(包括两端点)的所有数字。区间内排名为 k 的值指区间内从小到大排在第 k 位的数值。(位次从 1 开始)输入格式第一行包含两个整数 n,m,表示数列长度以及操作次数。第二行包含 n 个整数原创 2020-09-19 22:44:34 · 315 阅读 · 0 评论 -
单调队列优化DP——围栏
传送门题解:这道题只有两种状态,一个是工人,一个是砖,那么我们就可以定义我们的函数f[i][j]f[i][j]f[i][j]代表的是到第i个工人刷到j块砖所花费的代价。定义完状态过后我们开始划分集合,第一种就是第i个工人不刷那么就是f[i−1][j]f[i-1][j]f[i−1][j],然后就是第i个工人刷,刷的话又分不刷第j块砖,就是f[i][j−1]f[i][j-1]f[i][j−1],然后就是刷第j块砖,因为这道题是连续刷,那么也就是刷到第j块砖。我们可以从[1,j]…[j,j]这样的区间来刷砖原创 2020-07-17 23:45:25 · 100 阅读 · 0 评论 -
并查集——E.Merging Towers
题解:神奇的一道题,首先我们考虑如果我们一个个的搬这个碟子的话答案是n-1,但是如果我们有两个相邻的碟子是临近的那么就可以把他们看成一个整体这样的话答案就可以减去1了。我们按照每堆的top点建立树,每次合并的时候,对于小树的每个节点我们都判断它在原数组的相邻节点的祖先节点是不是合并的大树top点,如果是的既然相邻那么他们的半径就是差值最小的,也就是说可以把他们看成一个整体了答案就可以减去1了,然后再改变小树的祖先节点和原数组中记录的top节点改变就行了。#include<bits/stdc++.h原创 2020-07-14 13:54:01 · 207 阅读 · 0 评论 -
单调队列——牛客多校第二场F
题解:维护一个单调下降的单调队列,分别对每一行最大值和每一列最大值进行维护,最后当i,j大于k的时候分别跑每个子矩阵的最大值。#include <bits/stdc++.h>using namespace std;const int N=5010;typedef long long ll;int a[N][N],que[N],maxn[N][N];int lcm(int a,int b){ return a*b/__gcd(a,b);}signed main(){原创 2020-07-13 18:42:09 · 87 阅读 · 0 评论 -
线段树——Cloud Computing
题解:按照价格来进行建立线段树,维护总价格和总物品数信息。#include <bits/stdc++.h>#define int long longtypedef long long ll;#define lowbit(x) x&(-x)using namespace std;typedef long long ll;#define lson u<<1#define rson u<<1|1const int N=1e6+10;int n,k,原创 2020-07-10 23:31:57 · 117 阅读 · 0 评论 -
树状数组——Codeforces Beta Round #12 (Div 2 Only)D Ball
题解:看起来像三维偏序的问题,实际上不是,我们首先吧x按照从大到小的顺序来排就解决掉一维了,这里需要注意,如果x不相等那么y应该从小到打来排序,因为如果先插入的是y大的,那么再插入y小的时候答案就会加一,但其实x是相等的不应该加。y的处理方式是离散化之后用树状数组,并且插入的权值是z的权值。#include <bits/stdc++.h>//#define int long longtypedef long long ll;#define lowbit(x) x&(-x)us原创 2020-07-10 20:02:54 · 90 阅读 · 0 评论 -
树上莫队——Tree and Queries
题解:求出dfs序,然后树上莫队就可以出来了。#include <bits/stdc++.h>//#define int long longtypedef long long ll;#define lowbit(x) x&(-x)using namespace std;const int N=2e5+10;int n,m,c[N],ne[N<<1],head[N],e[N<<1],cnt,tot,in[N],out[N],dfn[N],block,原创 2020-07-10 13:08:26 · 97 阅读 · 0 评论 -
二分+树状数组——51nod 平均数
题解:题目让找第k大的平均数,可以转换为找平均数为x的个数是否大于等于k然后来进行二分。/* * 有多少个区间的平均数>x的有多少个 * sum[r]-sum[l-1]/(r-l+1)>x * 这样的区间标志是: * sum[r]-r*x>sum[l-1]-(l-1)*x */#include <bits/stdc++.h>//#define int long longtypedef long long ll;#define lowbit(x) x&原创 2020-07-09 20:55:28 · 110 阅读 · 0 评论 -
优先队列——51Nod逛街
题解:比较好的一道题,我们定义三个堆,q1,q2,q3,前两个堆维护的要去的商店,q3维护的是不去的商店。当q1中的数量大于k之后我们就可以讨论q2和q3了,如果我们q2中有的时间大于q3的时间那么就可以交换,以便腾出更多的时间来逛更多的商店。#include <bits/stdc++.h>#define int long long#define lowbit(x) x&(-x)using namespace std;#define IT (int)const int N=原创 2020-07-08 20:17:51 · 115 阅读 · 0 评论 -
树状数组——51Nod1463
题解:我们将查询按照L从大到小进行排序。因为我们的B是一个排列,所以每个数的位置是唯一的。我们通过枚举区间左端点,从右到左可以做到不重不漏。在枚举过程中,知道bib_ibi的情况下必须要bjb_jbj已经出现了才能添加(也就是位置要大于等于i)。最后树状数组维护区间最大值就行了。#include <bits/stdc++.h>//#define int long long#define lowbit(x) x&(-x)using namespace std;const i原创 2020-07-08 17:02:11 · 123 阅读 · 0 评论 -
线段树——稳定桌
题解:没想到线段树可以做这种题。。。这道题通过枚举留最高的桌子,首先比这个高的桌子肯定全没了,剩下的如果这个桌子的数量已经大于2倍那就不用再砍脚了,如果不够那么就砍掉前k小权值的桌脚。所以线段树维护的权值L到R区间内的数量和权值和。这道题也可以用权值线段树来做,之后来补上来。#include <bits/stdc++.h>#define int long longusing namespace std;#define lson u<<1#define rson u<原创 2020-07-07 21:39:45 · 74 阅读 · 0 评论 -
HDU3973——线段树+字符串哈希
题解:给我们n个单词,然后一个模式串,然后两种区间操作,一种是单点修改一个单词,一种是查询一个区间内是否是一个单词。我们线段树维护区间哈希值。然后区间查询操作和区间。#include <bits/stdc++.h>using namespace std;#define lson u<<1#define rson u<<1|1const int N=1e5+10,p=131;typedef unsigned long long ull;set<ull原创 2020-07-07 19:40:15 · 375 阅读 · 0 评论 -
线段树+二分——HDU6070
题解:题目让我们求type(l,r)/(r-l+1)的最小,显然可以用01分数规划,来二分求最小答案。所以我们从左往右移动端点,来统计种类。线段树来维护type(l,r)+l*mid的值。#include <bits/stdc++.h>using namespace std;const int N = 1e6 + 7;const double eps = 1e-7;double sum[N];int lazy[N];int pre[60007];int a[60007];in原创 2020-07-06 19:40:16 · 126 阅读 · 0 评论 -
线段树+状压——Multidimensional Queries
题解:我们以二维为例,将曼哈顿求和的绝对值拆开,对于一个x来说要么加他x或者是-x,所以我们用1表示x,0表示-x。因为k<=5。所以我们考虑对每一种状态建立一颗线段树。最后再区间统计。#include <bits/stdc++.h>using namespace std;#define lowbit(x) x&(-x)typedef long long ll;#define lson u<<1#define rson u<<1|1const原创 2020-07-06 14:46:51 · 127 阅读 · 0 评论 -
cdq分治——Codeforces1045G AI robots
题意:给n个机器人的所在位置,和他们交流半径,如果半径内的机器人智商相差k以内就可以进行交谈。题解:我们列出方程式,如果xi+1+rx_{i+1}+rxi+1+r>=xix_ixi>=xi+1−rx_{i+1}-rxi+1−r,并且智商差的绝对值小于等于k则可以交流。如果我们按照r的权值从大到小排序,当我们右边的能看到左边的时候,左边一定能看到右边。所以就降了一维了,所以就是三维偏序问题。#include <bits/stdc++.h>using namespace原创 2020-07-05 19:57:18 · 180 阅读 · 0 评论 -
线段树——E - A Simple Task
传送门题解:想了一天,码了半天,数据结构还是太菜了。线段树存储区间内每个字母的个数,最后输出的时候查询叶子节点存的是哪一个字母然后输出就行了。#include <bits/stdc++.h>using namespace std;const int maxn=1e5+10;#define lson u<<1#define rson u<<1|1struct Node{ int l,r,lazy; int num[27];}tr[maxn原创 2020-06-29 15:48:40 · 210 阅读 · 0 评论 -
线段树——Maze 2D
传送门题解:这道题实在太妙了,开始我以为是建立两科线段树,分别统计两排*的数目,后来看了题解明白,我们把2X1的长方形看成叶子节点,分别统计他们左上到右上,左上到右下,左下到右上,左下到右下4个方向,当然如果 是叶子节点同层移动就是0了。最后判断两个坐标的相对位置,然后因为我们是从左到右,在代码中保证了x<y所以交换了顺序以后可能会求右到左,但是他和左到右是等价的,所以这个时候需要判断一下。#pragma GCC optimize("-Ofast","-funroll-all-loops")#原创 2020-06-28 10:22:35 · 173 阅读 · 0 评论 -
主席树+LCA——Count on a tree
传送门题解:找u->v上面的第k大的权值,那么先要把这条链的信息给截取下来,也就是:rt[u]-tr[lca]+rt[v]-rt[fa[lca]]#include<bits/stdc++.h>using namespace std;const int maxn=400005;const int tp=18;int n,m;int root[maxn],lson[maxn*20],rson[maxn*20],tsize[maxn*20];int ne[maxn<<原创 2020-06-21 19:26:23 · 115 阅读 · 0 评论 -
hdu5145——莫队+多重集全排列
传送门对于区间查询且不带修改,加上多重集合的公式,我们很容易想到莫队,边界的转移也很容易写出来。(多重集全排列n!/(ai!+...+an!)n!/(a_i!+...+a_n!)n!/(ai!+...+an!))#include<bits/stdc++.h>using namespace std;typedef long long ll;const int maxn =3e4+5;const int mod=1e9+7;ll powmod(ll x,ll y){ll t; f原创 2020-06-15 22:51:26 · 92 阅读 · 0 评论 -
HDU3938
传送门题解:MST+并查集。最长路的最小边一定是在最小生成树中。我们按照边权从小到大排序。小集合的答案一定包含在大集合里面。当我们形成两个联通块的时候再加一条边进来能够联通并且满足条件的那么这条边一定是最长的最小边。方案数也就是两个联通块的节点数相乘。#include <bits/stdc++.h>#define LL long long#define N 10050using namespace std;struct node{ int a, b, c, i; bool op原创 2020-06-15 16:37:23 · 224 阅读 · 2 评论 -
树状数组+二分——HDU5493
传送门题解:因为有限制的是比当前人更高的人才有限制。所以如果之前安排的人都比这个人的身高低的话那么不会造成任何贡献。所以相当于按照空位插空,如果需要安排的人数大于空位数显然是无解的。空位数用树状数组存,因为位置越向右前面被占的位置越多,留下的空位越少,所以具有二分性。那么就有两种情况,一种是插左边,那么空位数就需要num+1个,如果之前的人和比他高的人都插右边的话就需要n-i-num+1个。取min就满足字典序最小了。#include<bits/stdc++.h>//#define i原创 2020-06-09 19:27:52 · 116 阅读 · 0 评论 -
Dr. Evil Underscores——字典树
Dr. Evil Underscores题解:看到异或就能想到字典树,这道题最大位数是30位,我们按照高位开始贪心,如果字典树上这一位既有1又有0,那么无论我们X的这一位选择什么去异或都会是1(先要保证最大值),然后分析这一位只有1或者只有0的时候那么我们的决策就可以选择和这一位相同的数把这一位给约掉从而保证最小。然后通过分治去解决就好了。#include <bits/stdc++.h...原创 2020-03-05 14:23:42 · 169 阅读 · 1 评论 -
Bathroom terminal——tril树
Bathroom terminalSmith wakes up at the side of a dirty, disused bathroom, his ankle chained to pipes. Next to him is tape-player with a hand-written message “Play Me”. He finds a tape in his own back...原创 2020-02-22 18:55:21 · 221 阅读 · 0 评论 -
YJJ's Salesman——树状数组+dp+离散化
YJJ’s SalesmanProblem DescriptionYJJ is a salesman who has traveled through western country. YJJ is always on journey. Either is he at the destination, or on the way to destination.One day, he is g...原创 2020-02-21 11:16:35 · 130 阅读 · 0 评论 -
Distinct Values
J - Distinct ValuesChiaki has an array of n positive integers. You are told some facts about the array: for every two elements ai and aj in the subarray al…r (l≤i<j≤r), ai≠aj holds.Chiaki would l...原创 2020-02-20 17:44:04 · 166 阅读 · 0 评论 -
Problem E. TeaTree——树上启发式合并
A - Problem E. TeaTreeRecently, TeaTree acquire new knoledge gcd (Greatest Common Divisor), now she want to test you.As we know, TeaTree is a tree and her root is node 1, she have n nodes and n-1 ed...原创 2020-02-19 19:32:02 · 230 阅读 · 0 评论 -
DP+矩阵快速幂+kmp——GT考试
GT考试阿申准备报名参加 GT 考试,准考证号为 n 位数 X1X2⋯XnX_1X_2⋯X_nX1X2⋯Xn,他不希望准考证号上出现不吉利的数字。他的不吉利数字 A1A2⋯AmA_1A_2⋯A_mA1A2⋯Am 有 m 位,不出现是指 X1X2⋯Xn 中没有恰好一段等于 A1A2⋯AmA_1A_2⋯A_mA1A2⋯Am,A1A_1A1 和 X1X_1X1 可以为 0。输...原创 2020-02-11 22:38:09 · 204 阅读 · 2 评论 -
AC自动机+dp——单词
单词某人读论文,一篇论文是由许多单词组成的。但他发现一个单词会在论文中出现很多次,现在他想知道每个单词分别在论文中出现多少次。输入格式第一行一个整数 N,表示有多少个单词。接下来 N 行每行一个单词,单词中只包含小写字母。输出格式输出 N 个整数,每个整数占一行,第 i 行的数字表示第 i 个单词在文章中出现了多少次。数据范围1≤N≤2001≤N≤2001≤N≤200,所有单词...原创 2020-02-08 22:18:37 · 218 阅读 · 0 评论 -
AC自动机+状态机dp——修复DNA
修复DNA生物学家终于发明了修复DNA的技术,能够将包含各种遗传疾病的DNA片段进行修复。为了简单起见,DNA看作是一个由’A’, ‘G’ , ‘C’ , ‘T’构成的字符串。修复技术就是通过改变字符串中的一些字符,从而消除字符串中包含的致病片段。例如,我们可以通过改变两个字符,将DNA片段”AAGCAG”变为”AGGCAC”,从而使得DNA片段中不再包含致病片段”AAG”,”AGC”,”...原创 2020-02-08 19:44:15 · 582 阅读 · 0 评论 -
AC自动机——搜索关键词
搜索关键词给定 n 个长度不超过 50 的由小写英文字母组成的单词,以及一篇长为 m 的文章。请问,有多少个单词在文章中出现了。输入格式第一行包含整数 T,表示共有 T 组测试数据。对于每组数据,第一行一个整数 n,接下去 n 行表示 n 个单词,最后一行输入一个字符串,表示文章。输出格式对于每组数据,输出一个占一行的整数,表示有多少个单词在文章中出现。数据范围1≤n≤1041≤...原创 2020-02-08 16:39:20 · 455 阅读 · 0 评论 -
treap——营业额统计
营业额统计Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况。Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额。分析营业情况是一项相当复杂的工作。由于节假日,大减价或者是其他情况的时候,营业额会出现一定的波动,当然一定的波动是能够接受的,但是在某些时候营业额突变得很高或是很低,这就证明公司此时的经营状况出现了问题。经...原创 2020-02-07 21:38:52 · 223 阅读 · 0 评论 -
treap——普通平衡树
普通平衡树您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:插入数值x。删除数值x(若有多个相同的数,应只删除一个)。查询数值x的排名(若有多个相同的数,应输出最小的排名)。查询排名为x的数值。求数值x的前驱(前驱定义为小于x的最大的数)。求数值x的后继(后继定义为大于x的最小的数)。注意: 数据保证查询的结果一定存在。输入格式第一行为n,表示操作的个...原创 2020-02-07 20:26:53 · 109 阅读 · 0 评论 -
KMP——KMP字符串
KMP字符串给定一个模式串S,以及一个模板串P,所有字符串中只包含大小写英文字母以及阿拉伯数字。模板串P在模式串S中多次作为子串出现。求出模板串P在模式串S中所有出现的位置的起始下标。输入格式第一行输入整数N,表示字符串P的长度。第二行输入字符串P。第三行输入整数M,表示字符串S的长度。第四行输入字符串S。输出格式共一行,输出所有出现位置的起始下标(下标从0开始计数),整数之间...原创 2020-02-06 17:40:39 · 117 阅读 · 0 评论 -
Tirl——Trie字符串统计
Trie字符串统计维护一个字符串集合,支持两种操作:“I x”向集合中插入一个字符串x;“Q x”询问一个字符串在集合中出现了多少次。共有N个操作,输入的字符串总长度不超过 105,字符串仅包含小写英文字母。输入格式第一行包含整数N,表示操作数。接下来N行,每行包含一个操作指令,指令为”I x”或”Q x”中的一种。输出格式对于每个询问指令”Q x”,都要输出一个整数作为结果,表...原创 2020-02-06 16:47:23 · 245 阅读 · 0 评论 -
Tirl——最大异或对
最大异或对在给定的N个整数A1,A2……ANA_1,A_2……A_NA1,A2……AN中选出两个进行xor(异或)运算,得到的结果最大是多少?输入格式第一行输入一个整数N。第二行输入N个整数A1~AN。输出格式输出一个整数表示答案。数据范围1≤N≤105,0≤Ai<231输入样例:31 2 3输出样例:3题解:从高位枚举,找和我们当前位不一样的,否则只有...原创 2020-02-06 16:45:48 · 242 阅读 · 0 评论