自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

转载 Typora导出PDF进行手动分页

https://blog.csdn.net/djfjkj52/article/details/105112512

2021-03-04 00:28:34 3089 1

原创 【解题报告】2020CCPC网络赛 1005 Lunch——SG打表找规律

CCPC网络赛1005,博弈论SG函数打表找规律我们可以发现这个实际上是个Nim游戏,问题的关键就是找到SG函数,可以先开搜:int get_SG(int x){ if(sg[x]!=-1) return sg[x]; if(x==1) return sg[1]=0; //如果数是1的话就不能继续分了,所以sg[1]=0 memset(vis,0,sizeof(vis)); for(int i=2;i*i<=x;i++){ if(x%i!=0) c

2020-09-24 14:22:41 329

原创 【解题报告】NOI1995 石子合并,POJ1179 Polygon,CH5302 金字塔——区间DP

复习几道区间DP的题:NOI1995 石子合并:题意:n个数,可以合并相邻的两个数,付出的代价是两数之和,问最后合并到一堆里的总代价最小是多少。思路:设计状态dp[i,j]表示[i,j]区间合并付出的最小总代价,最后求dp[1,n]。状态转移方程就是:dp[i] [j] = min{dp[i] [k] + dp[k+1] [j] + sum[i,j]} ,意思就是对于区间[i,j]的最小总代价为:枚举k,使得[i,k] 和 [k+1,j]区间的最小总代价和加上[i,j]区间数的和的值最小,就是[i,

2020-09-22 11:50:23 159

原创 【解题报告】BZOJ3307 雨天的尾巴——LCA+树上差分+动态开点权值线段树合并

树上差分+动态开点权值线段树+线段树合并的一道题思路:首先很容易想到树上差分,但是我们不是简单求和,还需要维护区间内数目最多的类型,可以想到权值线段树。所以我们就可以先树上差分,对于(u,v)链,我们在u点和v点的值+1,在lca(u,v)和fa[lca(u,v)]的值-1,这样在从叶子往上合并的时候就能还原成正常的序列。然后往上合并的时候需要维护数目最多的类型,所以需要用到权值线段树,于是就需要使用到线段树的合并。因为z的范围很大,所以需要先离散化一下,之后就进行线段树的操作就可以了。AC代码:/

2020-09-18 15:00:57 101

原创 【解题报告】POJ3417 Network——LCA+树上差分

倍增LCA+树上差分的一道题。问题关键是想清楚如何来计算方案数:对于新加入的一条边(u,v),我们将u->lca(u,v)->v这条路径上的点标注+1,然后最后遍历每个结点,如果这个结点的标注为0,则直接删除这条原边就可以将图分为两部分,对方案数的贡献为M,如果这个结点的标注为1,则删除这条原边后还需要删除对应的环的加入的新边才能将图分为两部分,对方案数的贡献为1。我们可以倍增求出来lca,但是直接在路径上记录还是复杂度高,所以考虑差分的思想,在u和v上标注值+1,在lca(u,v)上标注值

2020-09-15 21:31:25 113

原创 【解题报告】NOIP2007-树网的核 floyd+暴力水题

Floyd+暴力的水题,floyd预处理后直接暴力枚举路径以及对这个路径暴力求偏心距AC代码:#include <bits/stdc++.h>using namespace std;const int maxn=305;const int inf=3e5+10;int n,s;int a[maxn][maxn];int main(){ ios::sync_with_stdio(false); cin>>n>>s; for(int

2020-09-15 18:28:50 55

原创 【解题报告】BZOJ1912-巡逻 树的直径两种求法辨析和一点思维和边权取反操作

K=1的时候,直接取树的直径就可以,答案就是2*(N-1)-ans+1K=2的时候,我们首先依旧取树的直径,但是第二条连边由于一定要经过,所以两个环不能有太多重叠。因为重叠会导致本来走一次的路现在还是要走两次。然后我们考虑边为1,导致的结果是我们选择直径后能够让直径上的路径少走1次,所以如果边为-1,就是会多走1次。这样我们就可以处理K=2的情况,因为如果我们在新的直径上还经过了原来的直径的路径,那么重合的部分还是会走两次,所以我们把直径的路径上的边权都取反,然后再求一遍树的直径,答案就是2*(N-1)-

2020-09-15 14:59:32 115

原创 【学习笔记】splay复习

原来上数据结构学的,然而一直只会个基础操作,现在复习+做些题,这里留个板子splay板子基本操作:#include <cstdio>const int N = 100005;int rt, tot, fa[N], ch[N][2], val[N], cnt[N], sz[N];//rt:根节点编号//tot:节点数目//fa[i]:i的父亲//ch[i][0/1]:i的左右儿子//val[i]:节点权值//cnt[i]:权值出现次数//sz[i]:根为i的子树大小 str

2020-08-25 17:43:25 89

原创 【数学建模学习】2016A总结

2016A论文总结:第一问:首先对浮标进行静力学分析,得到风倾角θ的表达式;对钢管、钢桶、重物球、锚链进行静力学分析,得到一堆方程,然后求解…这我感觉看他分析还是可以看得懂的,但是如果从零开始自己分析,可能就比较困难。而且,我感觉这本身不是我们的长处,硬分析也搞不过那些学机械建筑啥的。第二问:在第一问建立模型的基础上,对重物球的质量进行优化,以重物球质量为目标函数,求解满足约束条件的目标函数最小值。整体来说是第一问的附属品,关键在第一问受力分析。第三问:系泊系统设计,在模型一二的基础上增加近海

2020-08-18 22:21:55 451

原创 【数学建模学习】KNN板子+算法原理讲解和算法图留坑

看到一篇写的很好的博客,但是没找到之前看的那篇博客,放不了链接了orz(代码也是参考那篇博客)KNN板子说明:这里只提供二维数据的KNN板子,本来想找三维数据的,但网上查了好久也没有。如果遇到高维数据了还是要主成分分析降维。先明确他要干什么:给你一个训练集(包括数据和分类),给你一些测试用例,然后判断这些测试用例属于哪一类。板子如何使用:X,Y为训练集的数据,X为二维的数据,是一个n行2列的矩阵,Xi,j表示第i个样本的第j维的数据;Y为一个具有n个元素的数组,Yi表示第i个样本的类别。# X为列

2020-08-13 21:37:49 356

原创 【解题报告】POJ3237 Tree——树剖(给边权)

题目大意:给棵树,有边权,然后有三种操作:把第i条边的权值变成w;把x到y路径上的所有边的权值取相反数;查询x到y路径上所有边的权值的最大值。思路:还是老套路把边权下放到点权,有点不同的是这回维护的是最大值,也正因如此,第二个操作:路径权值取相反数就可以比较简单实现了:x到y路径上的最大值取最小值的相反数,最小值取最大值的相反数就可以了。于是这道题就变成了写一棵维护最大值最小值,且支持单点修改,区间取相反数,区间查询的线段树;以及写一下点权边权转换的一些操作的题了。注意:区间最大值可能是个负数,所以中间

2020-08-12 02:26:43 195

原创 【解题报告】POJ2763 Housewife Wind——树剖

树剖,边权下放到点上,跟FZU2082一样。具体看这篇AC代码:#include <cstdio>#include <iostream>#include <algorithm>#include <cstring>using namespace std;typedef long long LL;const int maxn=1e5+10;struct edge{ int to,next; LL w;}e[maxn<<1];i

2020-08-11 20:12:56 82

原创 【解题报告】LightOJ - 1348 Aladdin and the Return Journey——树剖

裸树剖,注意多组数据和初始化的问题就好了。AC代码:#include <bits/stdc++.h>using namespace std;typedef long long LL;const int maxn=3e4+10;struct edge{ int to,next;}e[maxn<<1];int head[maxn<<1],cnt=0;int n;//节点数目int d[maxn];//d[i]表示第i个结点的深度int fa[maxn]

2020-08-11 19:05:47 94

原创 【解题报告】HDU3966-Aragorn‘s Story——树剖

裸树剖,注意多组数据和初始化的问题就好了。AC代码:#include <bits/stdc++.h>using namespace std;typedef long long LL;const int maxn=5e4+10;struct edge{ int to,next;}e[maxn<<1];int head[maxn<<1],cnt=0;int n;//节点数目int d[maxn];//d[i]表示第i个结点的深度int fa[maxn]

2020-08-11 18:52:58 81

原创 【解题报告】FZU - 2082 过路费——树剖

比较裸的树剖,但是给的是边权,这时候就要把每条边的边权下放到深度相对更深的点中。然后正常树剖操作。单点修改就改对应边深度深的那个点的点权,区间查询需要判断下:首先还是正常重边上查询,然后最后两点在同一条重边后,如果这两个点相同的话就不用再查询这个点的点权了,因为我们要看的实际是边,如果不同就要少算那个深度最浅的点,所以查的是son[x]和y(或者x的dfs序+1到y)之间的点权和。AC代码:#include <cstdio>#include <iostream>#includ

2020-08-11 18:36:46 117

原创 【数学建模学习】国赛2015看论文总结

国赛2015A看论文总结:一、拟牛顿迭代法求解目标函数:跟牛顿法不同的是:牛顿法在解决多变量问题的时候引入的H矩阵导致计算的复杂度上升,因此引入拟牛顿,主要有DFP和BFGS算法放个python的scipy的BFGS:from scipy.optimize import fmin_bfgsdef f(X): x1,x2=X return x1**2-4*x1+8+x2**2-4*x2+8def BFGS(): ans=fmin_bfgs(f,(0,0)) pr

2020-08-11 01:44:24 374 2

原创 【解题报告】洛谷P4396 [AHOI2013]作业——莫队+值域分块

n个数,m次询问,每回询问[L,R]内的<1>数值在[a,b]内的数的个数,<2>数值在[a,b]内的数值的个数很容易想到莫队套树状数组,开两个树状数组分别维护1和2,但复杂度为Nsqrt(N)logN,会T一个点:#include<bits/stdc++.h>using namespace std;typedef long long LL;const int MAXN=1e5+10;int N,M,B;int a[MAXN], pos[MAXN];int

2020-08-07 15:22:43 214

原创 【学习笔记】莫队算法&板子&几个模板题

参考原理看参考吧…关键就是要能离线,然后L和R指针变化时对答案的更新要O(1),最后的复杂度就是O(Nsqrt(N))要改的就是udpate函数,其他都是板子莫队板子:#include<bits/stdc++.h>#define MAXN 1000005using namespace std;typedef long long LL;int N,M,B;int a[MAXN], pos[MAXN];int ANS[MAXN];struct Req{ int L

2020-08-07 02:31:29 243

原创 【学习笔记】点分治&板子&几个模板题

参考:bdf,yyds**点分治:**又称树分治,主要功能就是在一棵树上,对具有某些限定条件的路径静态地进行统计的算法。其实主要是个树上分治解决路径问题的框架,具体问题需要具体处理。主要算法流程如下:<1>找树的重心作为根(保证递归的层数最少)int sz[maxn];//子树大小bool vis[maxn];//用于判断连通块int rt;//找到的根节点//找重心void dfs_rt(int now,int pre,int tot){ sz[now]=1; int n

2020-08-06 16:02:58 144

原创 【数学建模学习】K-means板子+算法原理讲解和算法图留坑

参考:这个板子板子使用说明:<1>板子提供二维和三维的K-means聚类,对于更高维的可以使用主成分分析法降维<2>板子中的K是需要人工调整的,来达到不同的聚类效果<3>二维和三维的数据输入格式:需要一个n*i的矩阵data,其中n为样本数(需要在代码中更改,代码中的n=150),i为2或3,是数据维数总的说是十分便捷的一个板子K-means原理:(想起来就写,再配几张好康的算法图板子:%二维:% 初始化工作空间clc;clear;% 载入数据

2020-08-05 01:06:31 309

原创 【解题报告】2020牛客暑期多校集训营第七场C题A National Pandemic——树剖

题目大意:给你一棵树,让你完成以下操作:<1>输入x,w,对任意结点y的权值加上w-dis(x,y)<2>输入x,让x的权值取min{F(x),0},其中F(x)为x结点的权值<3>输入x,输出结点的权值对于操作2很简单只需要用个delta数组记录,如果当前F(x)>0,则delta[x]-=F(x),反之则不用管然后来讨论重点的操作1:首先,w-dis(x,y)=w-dep[x]-dep[y]+2dep[lca(x,y)]分析这个式子可以发现,对于任

2020-08-04 14:38:26 172

原创 【学习笔记】树链剖分&板子

学完了LCT,写下总结&板子:参考:OIWIKI,这个博客树链剖分(LCT):这里说下最常用的轻重链剖分,首先定义重子节点:子节点中子树最大的子节点,其余的就是轻子节点;重边:从这个结点到重子节点的边,到其余的子节点为轻边;重链:若干条首尾衔接的重边构成重链。为什么要用重链剖分呢?因为它有几个很好的性质来方便地维护树上路径的信息:<1>重链剖分可以将树上的任意一条路径划分为不超过O(logn)条连续的链,每条链上的结点深度各不相同。<2>重链剖分还能保证划分出的每条

2020-08-04 02:09:03 194

原创 【学习笔记】树的重心

树的重心:对于一颗n个结点的无根树,找到一个点,使得把树变成以该点为跟的有根树时,最大子树的结点数最小,就是说如果删除这个点后,所形成的森林中,最大的树的结点数最小。性质:<1>树中所有结点到某个点的距离和中,到重心的距离和是最小的,如果有两个距离和,则他们的距离和一样。<2>把两棵树通过一条边相连,新的树的重心在原来两棵树重心的连线上。<3>一棵树添加或者删除一个结点,树的重心最多只移动一条边的位置。<4>一棵树最多有两个重心且相邻。dfs求树的

2020-08-03 01:22:00 212

原创 【学习笔记】倍增LCA板子

刚学了倍增LCA,留个板子,原理看OIwiki,洛谷,书什么的。#include <bits/stdc++.h>using namespace std;const int maxn=1005;vector<int> e[maxn];int n,m;int p[maxn][21];int d[maxn];bool vis[maxn];void init(){ for(int i=1;i<=n;i++) e[i].clear(); for(int i=1;i

2020-08-02 12:52:15 208

原创 【学习笔记】树的直径(两次dfs or 树形dp)

补一发第七场牛客C题补都补不动的图论fw的两发树的直径(开始图论我可以两次dfs:#include <bits/stdc++.h>using namespace std;const int maxn=10005;int n;vector<int> e[maxn];int lst=0;int ans=0;void dfs(int now,int pre,int dis){ if(ans<dis){ ans=dis; lst=now; } int

2020-08-02 01:14:56 114

原创 【解题报告】POJ - 3415 Common Substrings SA求两个字符串长度大于等于k的公共子串个数

求两个字符串的长度大于等于k的公共子串的个数。思路:首先我们可以发现实际上这个问题就是求解这个:(画个后缀数组出来就明白)ΣΣlcp(i,j)−k+1ΣΣlcp(i,j)-k+1ΣΣlcp(i,j)−k+1然后暴力求解的话就是枚举两个字符串的后缀,但这样复杂度会到n^2,所以考虑优化。这里可以用单调栈来维护,跑两边,一遍是s1入栈,s2来统计,一遍s2入栈,s1统计,两个答案一加就是总答案。具体思路可以看这个视频(类似的题目都是要求height数组的任意区间min):这里AC代码:#incl

2020-07-31 17:26:04 152

原创 【解题报告】POJ2774-Long Long Message SA求两个字符串的最长公共子串

求两个字符串的最长公共子串:即求对于各来自两个不同字符串的后缀的最长公共前缀的长度。如果直接枚举的话很显然复杂度比较高,所以这里考虑用一个没有出现过的字符来连接两个字符串,然后求这个新的字符串的height数组。但是这时不能直接Max{height[i]},因为有可能两个后缀是来自于同一个字符串的,所以我们再进行求最长公共前缀的时候要判断两个后缀分别来自于两个不同的字符串,求解即可。AC代码:#include <cstdio>#include <cmath>#include

2020-07-31 01:05:32 117

原创 【解题报告】SPOJ - REPEATS SA求重复次数最多的连续重复子串

求重复次数最多的连续重复子串。参考:这篇文章,和罗穗骞的国家集训队论文看了题解会的:论文上是这么写的,先穷举重复的子串长L,不妨从连续出现两次开始考虑,然后一定有s[1],s[1+L],s[1+2L]…中相邻的两个在我们要求的这个连续重复子串中存在。所以就对于s[1+iL]和s[1+(i+1)L]同时往前往后匹配,匹配出一个总长度K,则会有连续出现了K/L+1次,这个可以这么理解:从1+iL走到1+(i+1)L-1处相当于走完了一个重复的子串,如果那个也能匹配相当于有两个连续,当然如果走不到的话就只有一

2020-07-30 16:43:10 112

原创 【解题报告】2020牛客暑期多校集训营第二场J题——置换问题

一个置换的问题:给你n和大质数k,以及一个排列A,让你求得一个置换P,使得P走k次能到A,输出进行一次P置换的结果。对于排列O={1,2,3,…,n},我们经过k次置换P得到了排列A(已知),要求经过1次置换P得到的排列B(未知)。令A再做z次置换,达到原排列O。相当于:P^k=APzk=Az=O所以:zk%siz=0,siz为环长。也就是说我们如果对已知的A再做z次置换,就能得到O,我们要求的是由O再经一次置换P得到的排列。因此就有zk%siz=1,即求k模siz的乘法逆元。找到这个你元后对

2020-07-30 14:55:00 138

原创 【解题报告】HDU4436-str2int 广义SAM

考虑后缀自动机,首先先用个siz数组来记录到这个状态的子串的次数,用sum数组来表示到这个状态的和。于是我们就能找到个公式就是对于数j来说,sum[mp(i,j)]+=10sum[i]+j*siz[i],意思就是到状态i有siz[i]个子串,走数j的话,那就相当于当前的数乘10然后再加上现在的数。然后这个是要用拓扑序来走的,从小到大,走的时候同时还要求siz,siz[mp(i,j)]+=siz[i]。可以随便找个SAM试试就明白。然后由于有前导0的存在,所以从根节点开始走的话不能走0,为什么的话用一个SA

2020-07-30 01:28:26 107

原创 【解题报告】HDU4622-Reincarnation SA解法

后缀数组解法:这个其实和求字符串的不同子串类似,都是用所有子串的总数减去height,即重叠的部分,但是问题的关键在于全局的后缀排序不一定对应上局部的后缀排序,因此对于两个排名为pre和now的后缀,如果其局部的排名跟全局一样,则需要令pre=now;反之不一样的话就不用更新pre。这块可以这么理解:如果跟全局一样,我们已经处理了之前的pre和now,那么接下来顺着now继续就可以,反之就需要将二者交换,在这里可以直接不动pre就代表着交换,因为now被跳过去了。然后问题就转变为如何判断局部排名是否的全局

2020-07-29 18:06:03 108

原创 【解题报告】HDU3518-Boring counting SA

考虑后缀数组,还是很套路的题,就是枚举长度,然后变成判别性问题,对于长度k,我们可以遍历height数组,连续的长度>=k的分到一组,如果一个组里最大的sa[i]减去最小的sa[i]的话就可以不重叠的获得长度为k的重复次数>=2的子串,对答案贡献+1.AC代码:#include <bits/stdc++.h>using namespace std;const int maxn=2e3+10;typedef long long LL;char s[maxn];int y[

2020-07-29 11:33:23 96

原创 【留坑】HDU4416-Good Article Good sentence SAM

自闭太久了,留个坑,有时间了试试用后缀数组做做。

2020-07-29 00:28:09 66

原创 【解题报告】2020牛客暑期多校集训营第六场K题——RMQ+离散化

题目大意:定义k-bag为k的随机排列的循环(比如:1 2 3 3 2 1 2 1 3 3 1 2这种),定义part-k-bag为k-bag的一个连续子序列,给你个序列,长度为n及其对应的k,判断是不是part-k-bag。思路:首先序列肯定满足前面有一段不完全排列(当然也有可能是全的),中间连续好几段完全的排列,后面又一段不全的,所以就可以从开头的这段不完全的开始一个个作为起点试,如果发现走得通就输出YES,如果开头每个都试完了还是走不通就输出NO。之后就可以考虑怎么来判断中间那段是不是连续的好几段完

2020-07-28 21:37:46 70

原创 【解题报告】2020牛客暑期多校集训营第六场J题——线段树+置换群幂运算

线段树解决约瑟夫环问题+置换群的性质。线段树这个很像POJ2886那个题,就是删数,然后找现存的数的第k个数在哪。思路:先用线段树解决第一次k-Josuphus处理,得到置换群,由于置换群符合结合律,所以就变成了ans初始化为1,2,3,4,5,之后进行p1x1,p2x2…的置换,其中p1是通过线段树找到的,然后同时进行置换群快速幂。置换群快速幂:参考#include <bits/stdc++.h>using namespace std;const int maxn=1e5+10;i

2020-07-28 17:40:15 109

原创 【解题报告】2020牛客暑期多校集训营第四场C题——广义SAM

首先我们可以发现第二层函数没用,就提供了个约束的作用,对字符串没有改变的效果。又因为第一层函数对字符串的改变效果随后缀的改变而改变,且子串可以表示为后缀的前缀。因此我们就可以发现,这个本质上是在求字符串n个经函数改变后的后缀的本质不同的子串总数。于是可以想到用广义SAM,n个字符串求子串个数,直接∑(len[i]-len[fa[i]])就行了,但是这道题n=1e5,直接暴力建广义SAM肯定会炸,于是这么考虑:从后往前扫描,对于每个i,往后找到第一个大于等于s[i]的j,然后就会提供贡献s[i,j-1],直

2020-07-27 01:41:19 121

原创 【解题报告】2020牛客暑期多校集训营第五场B题

我们可以这么思考:对这棵树加边,加到完全图,边权为题目里给定的两点间路径的异或和,这样是符合提议中对该图的处理的,之后开始删边,由于要联通,所以就是求该完全图的最小生成树。但是直接加边时间空间都会炸掉,所以这里考虑一类问题:XOR最小生成树,该问题一般给出每个点的点权,然后两点间的边权为两点的异或,然后求该图的最小生成树,解决该问题的办法就是在01Trie上分块块。于是我们就可以处理这个问题:首先预处理出来结点0到任意一点路径xor异或和,然后就可以作为点权,来处理这个XOR最小生成树问题,在01Trie

2020-07-26 18:39:12 73

转载 【学习笔记】XOR最小生成树——01Trie+分治

终于看到一篇讲的详细的XOR最小生成树了,记录下:点这里

2020-07-26 17:38:29 145

原创 【解题报告】2020牛客暑期多校集训营第五场E题

队友考场上找规律找到的…下来发现是置换群的问题,之后有时间去学。思路就是找循环节,然后找每个循环节之间的最小公倍数,就是答案。然后再记个java的高精(java真好用,但好像直接dfs找会爆栈?AC代码:import java.math.BigInteger;import java.util.Scanner;public class Main{ static int maxn=100005; static boolean vis[]=new boolean[maxn];

2020-07-26 12:17:10 93

原创 【解题报告】SPOJ - SUBLEX Lexicographical Substring Search 后缀自动机

给定字符串S,Q个询问,每次询问第k大的字符串(去重)思路:首先我们知道自动机里存了所有不同的子串,如果我们询问第k大直接dfs找是肯定要炸的,所以考虑在每个结点处先预处理出来经过这条路能找到几个字符串,然后在找第k大的时候就可以直接判断走不走这条路径。几点细节:每个结点基础就会有一个路径,因为直接走一个字符能到这个结点;找第k大的时候会有一些+1或者-1的操作,因为起始节点是空字符串。AC代码:#include <bits/stdc++.h>using namespace std;

2020-07-24 23:33:08 109

空空如也

空空如也

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

TA关注的人

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