自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(93)
  • 收藏
  • 关注

原创 I. Ice Cream Shop

做法 :每一个点都有一个对应的是否能取到的区间,在这个区间内便可被取到,因此可以双指针预处理出区间,并使用差分获得各个值即可。看了大佬的代码,感觉码风非常好,故记录下来。#include <bits/stdc++.h>using namespace std;typedef long long ll;const int N = 1e4 + 7;const ll inf = 1e18;int n,m;ll ans;int main(){ cin >&g.

2022-04-27 10:57:37 449

原创 D. Optimal Partition(dp + 树状数组维护)

通过树状数组维护时候,记得添加初始元素0,使得维护元素为空的情况(也就是代表前缀和是s[0])#include<bits/stdc++.h>#define ll long long#define endl '\n'#define PII pair<int,int>using namespace std;const int inf=0x3f3f3f3f;const int mod=1e9+7;const double eps=1e-8;const int N=5.

2022-04-26 16:26:55 399

原创 点分治入门

点分治,是一种针对可带权树上简单路径统计问题的算法。本质上是一种带优化的暴力,带上一点容斥的感觉。注意对于树上路径,并不要求这棵树有根,即我们只需要对无根树进行统计。接下来请把无根树这一关键点牢记于心。下面给出一道例题 : poj的1741对于不合法路径,我们该如何删除呢?我们可以这样来处理:不妨假设当前的父亲节点是图中的点A,其遍历到了儿子B,对于不合法路径,其实就相当于要筛除以B2为父节点来计算的路径不超过K的个数 ,这是因为若以B为父节点,原先不合法的合并在B中..

2022-04-12 17:02:02 398

原创 线性基重要性质

线性基三大性质:原序列里面的任意一个数都可以由线性基里面的一些数异或得到。 线性基里面的任意一些数异或起来都不能得到00。 在保持性质一的前提下,数的个数是最少的。考虑一个问题:我们假设数的最高范围是2的32次方,那么如果我们可以从中选出32个以上的数,是否一定可以保证异或和为0呢?答案是肯定的:不妨这样理解,每一次插入,都有成功与不成功,如果成功,说明对某一位有贡献,如果不成功,说明线性基已经可以构成这个数,那么,最坏情况32次之后,就一定可以实现异或和为0的操作了。可以去看看这题:N.

2022-04-05 16:57:20 4069

原创 树状数组维护前缀和

#include <iostream>#include <cstring>#include <algorithm>#include <vector>using namespace std;#define int long longconst int N = 400010;int s[N];int tr[N];int n,m;vector<int>nums;int lowbit(int x){ return x&...

2022-04-02 19:42:37 142

原创 区间离线问题----莫队算法例题取根号n时间复杂度证明

莫队算法:其核心思维就是对于 区间查询 操作,通过对所有 “被询问的区间进行” 合理的排序 ,然后通过 暴力移动区间的左右端点 并 快速更新答案 得到所有询问的结果。-----摘自这里题目链接:小Z的袜子细节问题这里不诉说了,下面来证明一下如何计算时间复杂度以及为何这样最优。对于这一问题的证明如下:代码如下:#include<bits/stdc++.h>using namespace std;const int N ...

2022-03-30 16:43:21 669

原创 蓝书----分块模板

利用暴力-----局部朴素,大段维护,极具美感。#include<bits/stdc++.h>using namespace std;typedef long long ll;const int N = 100010;int n,m;ll a[N],sum[N],add[N];int pos[N];int L[N],R[N];void change(int l,int r,ll d){ int p = pos[l],q = pos[r]; if(p == q) .

2022-03-28 21:41:34 203

原创 第一届ACC(AcWing Cup)全国高校联赛(决赛)题解

第一题过于简单就不说了。第二题:合并石子,看题目以为是个区间dp但是其实不难发现性质:切割之后的最终态,每一堆都一定匹配一个l1,r1于是可以双指针,每匹配到相同的数就分出来即可。#include<bits/stdc++.h>using namespace std;const int N = 1e5 + 10;int a[N];int b[N];int n,m;int main(){ cin >> n >> m; for

2022-03-28 21:09:53 617

原创 DFS序维护树状数组

dfs序是指:每个节点在dfs深度优先遍历中的进出栈的时间序列。如图,当我们维护一个时间戳,即每个节点进栈与出栈的时间,便可以把树上问题转换为区间问题。例题如下:当我们需要对树上问题进行区间求和的时候,如果我们可以把树上问题转为区间问题,便可以很方便的利用数组数组以及线段树去维护序列,#include<bits/stdc++.h>#define int long long using namespace std;const int N =...

2022-03-27 17:42:51 1002 3

原创 Red Black Tree

B - Red Black TreeZOJ - 4048二分加 lca关键问题在于判断过程 , 当我们选中一个答案时,我们先看看集合内有哪些数比它大,并看看能不能把这些数进行修改。下列情况无法取该答案:1.取到公共祖先的时候更新后的距离 仍比 选中的答案来的要大。(前提:节点与公共祖先之间没有其他红色节点)2, 节点与祖先之间已经有红色节点了(或者这个祖先本身就是红色节点),这个时候无法更新距离,因为题目要求每个点的距离是最近红色祖先的距离,这个时候便无法更新。#incl...

2022-03-26 21:18:06 725

原创 目前做过的最长的线性dp-- I--区域

启发了对状态转移的设置#include<bits/stdc++.h>using namespace std;int n,m,k;int w[16][16];int f[16][16 * 16][16][16][2][2];struct state{ int i; int j;int l;int r;int x;int y;}g[16][16 * 16][16][16][2][2];int main(){ cin >> n .

2022-03-24 15:41:18 688

原创 实用算法--对顶堆法--查询区间中位数

unning Median维护一个大根堆一个小根堆,假设当前m个数,大堆储存第1-m/2大的数,小根堆有第m/2+1到m大的数,通过实时维护,小根堆的堆顶就是中位数(奇数区间的情况。) if(q2.empty()||x>q2.top())q2.push(x); else q1.push(x); while(q1.size() > i/2) {q2.push(q1.top());q1.pop();} whi

2022-03-14 17:40:34 489

原创 环形均匀纸片分牌问题证明

环形均分纸牌问题,就是将 n 个人排成一圈,则第一个人可以和第 n 个人传递纸牌。如果我们可以证明某两个人直接可以不用传递纸牌也能获得最优解,那么我们可以尝试断开每两个人之间的连接,然后使用非环形均分纸牌问题中的方法来求解。网上很多解答都是在可链化的基础上推出了求中位数求解的结论,然而关于可链化(即可以将某两个人的连接断开而不影响最少操作次数)的证明问题却语焉不详。实际上,想要通过枚举各种情况证明可链化是非常困难的,因为没有办法枚举所有情况。这题更严谨的做法应当是假设XiXi 表示第 ii

2022-03-14 15:43:42 560 1

原创 Manachar算法

今天补题遇到字符串,不太会看了题解发现是manachar算法。于是屁颠屁颠跑去补。。。https://blog.csdn.net/dyx404514/article/details/42061017这篇介绍的很好,容易理解。板子如下:int mar(string x){ string s="*"; int ans=0; int lenx=x.length(); for(int i=0;i<lenx;i++){ s+='#';

2022-03-09 21:22:25 287 2

原创 最优比率生成树

也就是01规划问题,用实数二分就可以解决。主要问题是使用克鲁斯卡尔算法会tle。。。(稠密图)#include<bits/stdc++.h>#define INF 0x3f3f3f3fusing namespace std;int n;int fa[1002];struct node{ double x,y,z;}a[1002];struct mode{ int x; int y; double z;};int get(int x){ if(

2022-03-09 13:17:01 358 2

原创 有度数限制的最小生成树问题--Picnic Planning

目前为止见过的最复杂的题了(对代码实现能力要求很高)。。。。。码了好久才想通。接下来来剖析步骤--1.先不考虑1号节点,跑一遍克鲁斯卡尔,这样得到的就是各个联通块内部的最小生成树(也就是森林)。2,。贪心的想,将每个联通块内到根节点最短的端点找出并连接。3. 连接之后我们假设用了t条边,而题目要求使用s条边,那么我们就还有(s-t)条边可以使用,因此我们可以考虑用与1直接相连的边的权值去删掉(1,x)中边权最大的边,(这样既可保持联通性,又减少了权值)。4.关键在于如何实现找到路径上

2022-03-08 20:38:17 515

原创 Cow Relays

题意:要求经过N调边的 S到E的最短路。解: 容易知道,经过两条边的最短路,只要枚举 A【i,k】+A[k,j] 即可,但是对于多条边,我们不妨拓展开来看,记为经过m条边到某点的最短路集合,,为经过q条边到某点的最短路集合,那么,经过 m+q 条边最短路不正可以通过枚举 中的 a[i,k] ,以及中的 a[k,j]枚举吗。(说明这种性质具有传递性)#include<bits/stdc++.h>using namespace std;int n,t,s,e;...

2022-03-07 16:44:31 120

原创 矩阵乘法。

1.关键问题在于如何去建立关系矩阵,观察本题,可以发现n与m非常小,因此,可以将整个矩阵压缩成 一行 (m*n + 1)列num(i,j) = (i - 1) * m + j; 代表压缩后各坐标在这个行列式中的位置。2.接着思考如何使用矩阵快速幂加快运算。注意到最长长度为6,1 - 6 最小公倍数为 6,因此我们每个60秒可以理解为一个周期,那么将t拆成, 用A 表示每个60秒内的关系矩阵,便可计算加快运算。3. 对于60秒内的各个关系矩阵,我们可以初始创找一个对角矩阵...

2022-03-07 15:00:44 254

原创 并查集应用

通常来说,并查集用来维护具有传递性质关系的集合,对于本题,可以巧妙使用并查集的地方在于:利用路径压缩,查找到还未使用的第一个数,例如 , 2已经被使用了,其父亲为4,4的父亲为100....可以实现高效率的查找。#include<iostream>#include<unordered_map>#include<cstdio> using namespace std;const int N = 5e5 + 10;unordered_map<int.

2022-03-03 13:59:08 409

原创 可持久化线段树(二) 例题篇(待补充)

1.数数肉眼可见的裸题,唯一需要思考的地方就是如何确定范围,不妨如此思考,我们已经知道寻找第k小数的方法,那么我们不妨先朴素的想:枚举区间第1小,第二小。。。。看看到哪都比H小,不就是这题的答案吗,因此,利用单调性,不妨使用二分法,确定端点,就是答案了。代码如下:#include<iostream>#include <cstdio>#include <algorithm>#include <vector>using namespace s.

2022-03-03 10:07:40 251

原创 可持久化线段树(一)

对于主席树,先说说个人理解(待补),相当于空间换取时间,只有数据范围不是那么大的时候才能使用一般开的空间为 N *4 + N *log N;具体实现的操作就是先copy一个原版本,之后再进行修改操作,再使用递归pushup上去,就完成了新版本的建立。 下面这道题,就是目前本人学到的主席树的第一个操作----查询定区间第k小的值,下面说说本人的理解。1.为什么可以使用可持久化线段树?试想一个问题,如果我们有方法 维护 落在 从小到大 【a,b】值域区间范围内的值的个数(初始化为0),那...

2022-03-02 22:14:25 374 2

原创 可持久化trie树

https://blog.csdn.net/weixin_43959739/article/details/84922554详情可以看这一篇,或者李煜东老师的书p253.下面来介绍一下本人理解的 建立可持久化trie树的过程。1.创建新版本的时候什么时候和之前版本的节点发生关系?私以为,不妨以下图为例,具体来说,就是将当前版本与之前版本都从根节点出发,将当前版本该节点出发没有,之前版本有的一些信息进行连接,很好理解,因为最新版本相当于目前所有版本的总和因此之前的信息就通过这种方式维护

2022-03-02 15:43:33 598

原创 哈希表模拟后缀数组

#include<bits/stdc++.h>using namespace std;const int sz = 3e6+ 10;char s[sz];int n;int f1[sz],p[sz],f2[sz];unsigned long long has1(int l,int r){ return f1[r] - f1[l - 1] * p[r - l + 1];}unsigned long long has2(int l,int r){ return f2[...

2022-03-01 18:14:07 140

原创 LCA板子题--Dis

先用dfs维护每个点到以1为根节点的异或和的d[n],接着,用lca找到最近公共祖先,由异或的性质a^b^b^c=a^c可以知道,d[a]^d[b] ^公共祖先就相当于最短距离#include<bits/stdc++.h>using namespace std;const int N = 200010, M = 2 * N;int h[N],e[M],ne[M],idx;int f[N][20],d[N],dist[N],edge[2 * N];int aq[N];int.

2022-02-28 16:35:46 324

原创 树形dp补题

1.变异蛮牛很显然要求的就是以一为起点到以一为终点的个数,对于一个节点分析,我们可以发现它的贡献可以分为:1.若该节点为黑的时候,可以与子节点为黑的节点相连,并且子节点之间也可以相连2.若该节点为白的时候,并且子节点之间也可以相连利用递归的思想,先处理每个节点中的黑点个数,再分类计数即可。(复杂度O(n))#include<bits/stdc++.h>using namespace std;int t;int n;const int N = 2e5 + 10,.

2022-02-28 14:10:06 100

原创 Accumulation Degree --- 换根dp

个人感觉,换根dp的实质就是在不确定答案是以哪个节点为根时,先假设1个节点为根去遍历,更新答案,接着利用数学公式推出该假设根的子儿子为根的时候对应的值。#include<iostream>#include<cstring>#include<vector>using namespace std;int n;const int N=400000+10;long long e[N],ne[N],idx,h[N],edge[N];bool vis[N];.

2022-02-28 13:13:56 149

原创 蓝书例题----树的直径 ---- 巡逻

做法蓝书上已经很清楚了,主要的问题就是---void update(int q,int p){ while(q!=p) { edge[pre[q]]=-1; edge[pre[q]^1]=-1; //无向边是有两条相邻的 q=e[pre[q]^1]; }}为什么这样可以给直径上的点标为 - 1 ,原因在于 由于树是双向路径,因此,取异或时,相当于原本记录的idx相邻的那一项,也就是自身的反方向。#includ.

2022-02-26 18:09:43 183

原创 名作之壁---单调队列回顾

【题解】牛客小白月赛27_ACM竞赛_ACM/CSP/ICPC/CCPC/比赛经验/题解/资讯_牛客竞赛OJ_牛客网来源:牛客网考点:尺取法+单调队列(维护最值)。设答案为ans,考虑使用尺取法,用右指针r遍历数组。若[l,r]区间内最大值与最小值之差大于k,则此时对答案的贡献为n-r+1。因为[l,r+1],[l,r+2],…,[l,n]区间的最大值只可能大于等于[l,r]区间的最大值,[l,r+1],[l,r+2],…,[l,n]区间的最小值只可能小于等于[l,r]区间的最小值。因此若[l,r]区

2022-02-25 20:48:34 773

原创 树上直径---巨木之森

定理---树上任意一点的最远点一定是树的直径的端点。可以发现,要想遍历完整颗树,再回到原来的位置,那么就要把每条边都走两遍,但是现在不需要回到原来的位置,所以只要找到离根节点最远的点,用总权值的两倍减去 这条最远边的长度就好了。于是,我们可以先以某点dfs,求出这点的最远距离----一定树直径的是某个端点p。再以该点p出发,dfs找出另一个端点 q;最后,再dfs q点求出所有点到q点的距离,之后计算,排序求解即可。#include<bits/stdc++.h>

2022-02-25 19:11:51 298

原创 E. Expand the Path ----Educational Codeforces Round 123 (Rated for Div. 2)

观察样例我们不难发现,关键点在于未偏移的时候的最右下角的坐标(若其触边界),如右边界,则无法整体右移,其他同理,接着分析如何计算覆盖的点,举个例子:当初始操作为D时,当还未遇到R之前,不适合进行偏移,那么就会有部分空白面积,当遇到R之后,可以计算第一个R之后右移动了多少记为cx,下移动了多少记为cy,留白面积就是cx*cy 可以自己造个样例去看看 我可以给个(6,DDDRRD),画个图就可以理解了。#include<cstdio>#include<cstring>..

2022-02-23 15:39:05 514 2

原创 Atlantis

主要这篇文章想说一些自己遇到的困惑1. 线段树维护的内容是什么,以y轴建立扫描线为例 ,我们知道当遇到两条边的时候间距很好求出,然而高度却不好求出,并且随着出边与入边的改变,在y轴上被划分的小矩形块的一直在变化,因此,需要维护的就是这个长度。2. 为什么这段代码当中 r要 -1 ,l 不用? l = lower_bound(ally + 1,ally + 1 + cnt,e[i].a) - ally; r = lower_bound(ally + 1,ally + 1 ...

2022-02-22 17:31:59 193

原创 线段树区间修改用到的懒标记

在代码中spread片段用来表示懒标记。个人理解,就是进行区间修改时,遇到查询区间完全覆盖目标区间的情况时,那么修改整个区间的数据时间复杂度是O(n)级别的,但是在查询答案时候,可能就用不到这个区间,因此我们给该区间加一个标记,当需要用到的时候再进行修改操作,以降低复杂度。但值得注意的是,一个点被标记的时候,往往其本身已经被修改过了,要做的是将标记传给它的子节点。例题:一个简单的整数问题2#include<bits/stdc++.h>using namespace std;c.

2022-02-22 13:21:29 648

原创 树状数组实践--求逆序对,区间修改,单点查询改单点修改,区间查询

先用数组数组维护一个c【x】 函数用于记录对应集合[l,r] 范围内数的个数,接着倒叙扫描给定1序列 a ,(1)每次查询前缀和 【1 , a[i] - 1】 累加到答案之中。(2)执行 “单点增加操作” 把 a[i]上的数加一 ,可以理解为扫描这个数之后,开始扫描这个数之前的数,那么就要更新一下数状数组了。由于是倒叙开点,那么当前形成的树状数组中,的值都是在这个数之后出现的数,所以查询【1 , a[i] - 1】,即可找到关于这个数的逆序对数。#include<bits/stdc+

2022-02-21 08:55:53 521

原创 2021.12.23--补题篇--小白白月赛30

A--黑白边发现了并查集可以用来判断图的连通性,本题的做法就是先连接黑边,然后在图连通的情况下,dfs,看哪些点还未在图中,吗,每次dfs相当于白边的数量加一。#include <iostream>#include <algorithm>#include <cstring>#include <string>#include <queue>#include <map>#include <stack>u.

2021-12-23 17:39:02 191

原创 Codeforces Round #762 ---C

水题,嗯模拟就完事,主要把握规律:有进位的地方的前一位一定要是1即可。#include<iostream>using namespace std;string a,s;int t;int main(){ cin>>t; while(t--) { string b; cin>>a>>s; int aq1=a.length()-1; int aq2=s.length()-1; int flag=1; int .

2021-12-21 15:00:46 188

原创 数位dp(计数问题,超短模板)

# include <iostream># include <cmath>#include <vector>using namespace std;int kNumbers(int n,int k){ if(!n) return 0; int res = 0; vector<int >ans; while(n){ans.push_back(n%10),n/=10;} f...

2021-12-12 14:58:52 219

原创 CF&Idea周训练-34--C - Bakry and Partitioning

样例图题意:给定一颗树,并告知(最多)可以去除多少条边,询问是否存在方案使得各个连通分量的所有节点异或值相同。题解: 不妨根据样例画图,我们可以发现,对于一颗树,如果其所有节点异或和为0,那么只要裁剪一次,获得的两个连通分量的异或值一定相同,这是因为异或的性质---相同值异或值为0.对于所有节点异或值不为0的情况,例如异或值为a,那么有解的情况最后一定可以是 至少分为3个部分,a,a,a,也许可以分为5个,7个部分,但是对于比3大的奇数,可以三个三个连边,最终结果和只有三个连通分...

2021-12-12 12:31:48 774 2

原创 树形dp(一)

例题;没有上司的舞会状态表示:f[i][j],一维表示当前这个节点,二维表示当前这个节点是选还是不选,根据选与不选可以写出不同情况的状态转移方程。#include<iostream>#include<cstring>using namespace std;const int N=6010;int e[N],ne[N],idx,h[N],f[N][N];bool vis[N];bool has_father[N];int n;int happy[N];vo.

2021-11-29 13:32:52 167

原创 补提篇--ICPC上海站--I

https://ac.nowcoder.com/acm/contest/24872/I当时写了个记忆化搜索,没注意到n=100......正解其实是dp。#include<bits/stdc++.h>#define LL long longusing namespace std;const int N = 101;const int M = 4105;const LL INF = 1e15;LL f[N][N][M];int n,k;LL v[N];int sum

2021-11-28 20:24:39 534

原创 好题分析---最短Hamilton路径+枚举优化

弄懂代码很容易,但是问题的关键是----为什么可以这么做??----对于状态的划分和转移,最关键的一点就是----不重不漏,对于确定的终点,我们应该要怎么设计方程呢?也就是说,要如何高效地枚举所有经过节点,并到达终点的情况。假设:一共有七个点,用0,1,2,3,4,5,6来表示,那么先假设终点就是5,在这里我们再假设还没有走到5这个点,且走到的终点是4,那么有以下六种情况:first: 0–>1–>2–>3–>4 距离:21second: 0–>1–>3–&...

2021-11-24 20:01:42 558

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除