- 博客(29)
- 收藏
- 关注
原创 ICPC2021 济南站 总结
大一省赛打星, 所以这场济南算是我队第一次比赛了。 PKU出题真是离谱。 一题手快铜, 两题手快银。 我队属于两题手慢的那个, 最后铜首没拿银。虽从结果上来看, 第一场就有铜, 还是不错的。 但还是落下了许多遗憾,包括C可以更快写出来, J也是可以做的。 这锅我背了,数学场把队友给演了, 数学选手简直崩溃。 吸取上海vp时的教训, 我们开场三人三线开题, 我从后往前看, 连着看了L、M、K三题都没什么想法, 就去跟榜了。这时C、D、K都有人过, 而K过的人更多。我就再回去看K了, K的大致意思是, 一个人B
2021-11-16 21:12:30
1417
原创 【模板】 Splay树
Messenger(板子题) #include <bits/stdc++.h> using namespace std; const int N = 2e5 + 10; const int inf = 0x3f3f3f3f; char str[N]; namespace Splay{ struct Node{ int son[2]; int fa, val, size, cnt; int rev; }t[N]; int root, tot; void push_up(
2021-11-07 19:00:39
146
原创 【模板】点分治
点分治有两种统计答案的方案 方案1:分别处理子树 在处理完一颗子树的后, 再将节点统一加进备选答案中, 可以避免同颗子树上的两点相互干扰 洛谷P3806 【模板】点分治1 #include<bits/stdc++.h> using namespace std; const int N = 1e4 + 10; const int LIMIT = 1e8 + 10; const int inf = 0x3f3f3f3f; int m; bitset<LIMIT> exist; int
2021-10-19 22:50:44
202
原创 【模板】可持久化trie
最大异或和 #include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for(int (i) = (a); (i) <= (b); (i)++) typedef long long ll; const int N = 6e5 + 10; const int inf = 0x3f3f3f3f; const int LEN_OF_BIT = 24; int s[N]; namespace trie_persiste
2021-09-16 19:48:00
113
原创 【模板】Treap
普通平衡树(模板题) #include <bits/stdc++.h> using namespace std; typedef long long ll; #define rep(i, a, b ) for(int (i)=(a);(i)<=(b);(i)++) const int N = 1e5 + 10; const int inf = 0x3f3f3f3f; namespace Treap{ struct Node{ int l, r; i
2021-08-26 16:55:18
71
原创 【模板】莫队算法
小Z的礼物 #include <bits/stdc++.h> using namespace std; typedef long long ll; #define rep(i, a, b ) for(int (i)=(a);(i)<=(b);(i)++) const int N = 5e4 + 10; int n, m, a[N], col[N], fz[N], fm[N]; int gcd(int a, int b){ return b == 0 ? a : gcd(b, a
2021-08-25 21:53:12
103
原创 【模板】线段树, 权值线段树
P3372 【模板】线段树 1 #include <bits/stdc++.h> using namespace std; typedef long long ll; #define rep(i, a, b ) for(int (i)=(a);(i)<=(b);(i)++) #define lson pos << 1 #define rson pos << 1 | 1 const int N = 1e5 + 10; ll a[N]; //struct Segmen
2021-08-14 20:32:36
91
原创 拉格朗日插值
简易版(只要求f(x)的值, 不要求求出系数还原多项式) P4781 【模板】拉格朗日插值 #include <bits/stdc++.h> using namespace std; typedef long long ll; #define rep(i, a, b ) for(int (i) = (a); (i) <= (b); (i)++) const int N = 2e3 + 10; const int mod = 998244353; ll x[N], y[N]; ll fas
2021-08-14 09:47:13
76
原创 【模板】FWT
还没弄懂FMT, FWT间得区别待填坑 P4717 【模板】快速莫比乌斯/沃尔什变换 (FMT/FWT) #include <bits/stdc++.h> using namespace std; typedef long long ll; #define rep(i, a, b ) for(int (i) = (a); (i) <= (b); (i)++) const int N = (1 << 17) + 10; const int mod = 998244353; ll
2021-08-14 09:31:06
114
原创 【模板】树链剖分
O(nlog2n)O(nlog^2n)O(nlog2n) 【模板】树链剖分 #include <bits/stdc++.h> using namespace std; typedef long long ll; #define rep(i, a, b ) for(int (i) = (a); (i) <= (b); (i)++) #define lson pos << 1 #define rson pos << 1 | 1 const int N = 1e6 + 1
2021-08-13 08:56:36
103
原创 【模板】网络流
Dinic算法(O(n2m)O(n^2m)O(n2m), 二分图O(mn)O(m\sqrt{n})O(mn)),可跑边数1e4~1e5的数据 小M的作物 #include <bits/stdc++.h> using namespace std; typedef long long ll; #define rep(i, a, b) for(int i = a; i <= b; i++) const int N = 3e3 + 10; const int M = 2e6 + 2000 + 1
2021-08-11 23:55:47
88
原创 Min_25筛解题报告
找素数 要求求出1e11以内的素数个数 这题有趣的是代码只求了g函数不用求S函数,试分析原因 g函数的意义是:前n个数中所有素数的贡献Σi=1n[i∈Prime]f(i)\Sigma_{i = 1}^{n}[i \in Prime]f(i)Σi=1n[i∈Prime]f(i) 而S函数是:前n个数的贡献Σi=1nf(i)\Sigma_{i = 1}^{n}f(i)Σi=1nf(i)(即积性函数的前缀和) 提要求素数个数,可构造函数f(x)=[x∈Prime]f(x) = [x \in Prime]f(
2021-08-10 13:20:24
167
原创 单调队列的做题思路(自看)
挺难理解单调队列的, 就写些自己平时思考到的小结论, 可能对解题有点帮助 不妨设队列是个单调递增队列,若当前遍历到第i个元素, 队列尾是第j个元素(可能已进行部分出栈操作) 1.1 a[k] > a[j], j < k < i 1.2 用que[tail]表示队尾元素编号,若a[i] < a[que[tail]], 则a[i] < a[que[tail - 1] + 1]. 也可单开一个left数组, 存大于a[j]的连续左区间内的最大值 Feel good ...
2021-07-20 13:48:43
129
原创 线段树的应用
已知线段树最基本的操作是对于数组的单点修改和区间查询,因此有了以下推广: 之一:对一棵树进行单点修改和子树查询(不论这棵树是否为二叉树,不论节点是否顺序编号): 时间复杂度O(logn)即线段树的操作时间,退化成链也一样 原因,线段树查询需要知道l 和r,当节点顺序编号时, l就是该节点的编号, 所以我们只需知道r即可完成查询操作。将整棵树进行一遍dfs, 就有r = l + size[l] - 1,其中size[l]为以l为根节点的子树大小(包括l) 而当节点不是顺序编号时, 另开两个数组idx[], 和
2021-04-14 11:27:01
233
原创 算术分解定理取根号的注意点
很多时候,对于一个数据范围很大的数,如n∈\in∈(1, 2e9)分解质因数,若循环n次就会超时,所以通常做法是循环n\sqrt{n}n次,再有因数的性质,算出大于n\sqrt{n}n的情况,然而此方法有些部分需要引起注意,以下代码为例 void find_prime_factor(int n) { for (int i = 2; i <= sqrt(n); i++) { if (n % i == 0) { prime[++cnt] = i; while (n % i == 0)
2021-03-12 22:55:23
402
原创 最小生成树
Kruskal的优化: 以Highways 这题为例 思路,点之间两两建边,利用kruskal和并查集,先连上已有的边(将边的两个端点放入一个并查集中),再将不同集合的边连接直到边数等于n 做题过程1:结构体2个(Point记录点坐标,Edge记录每条边的情况),优先队列(至今为止Kruskal用的好像都是这个?,每两个点之间建边,但是跳过在同意集合的两个点。其中建边的时间复杂度是O(n^2),KruskalO(nlogn),怎么看都不会超时的情况下,还是因为常数过大TLE了(黄色部分仍可优化) 每两个点之
2021-02-15 08:34:27
147
原创 背包
01背包: 一维数组dp方程 for(int j = n; j >= w[i];j--){ dp[j] = dp[j - w[i] ] +v[i]; } 多重背包: 1:将一个有x份物品的拆成x一份的物品,循环数倍扩大,时间复杂度受不了 2:二进制优化:原理:将一个数x用二进制表示后,每一位的0或1可表示1-x的所有数 int num = 0; for (int i = 1; i <= m; i++) { int a, b, c; scanf("%d%d%d", &a
2021-02-02 22:49:40
105
原创 最短路学习笔记
三种算法 floyd 复杂度 :O(n^3) 应用场景:多源最短路,非负边 邻接矩阵存图 最短路 #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int INF = 0x3f3f3f3f; int n,m; const int MAX_N = 105; int d[MAX_N][MAX_N]; int main() { while(scanf("%d
2021-01-30 22:37:18
89
原创 Hash
二维哈希公式: sum[i][j]=sum[i-1][j]*p+h[i][j-1]*p-h[i-1]j-1]*p *p+a[i][j] 先来看二维矩阵前缀和: 如图每个矩阵右下方的数字代表这个矩阵的前缀和下标;我们由数学公式sum4 = sum2 + sum3- sum1 +a[i][j]可得sum4 即sum[i][j] = sum[i-1][j] + sum[i][j-1] -sum[i-1][j-1] +a[i][j] 模仿一维哈希函数有: h[i] = h[i-1] *p1 h[j] = h[j-
2021-01-29 23:17:43
104
原创 dp
不知道是今天的题目有挑战性,还是自己太菜。很多题思路都不清晰。学长也是太看得起我们了,直接放一道EC-final赛的银牌题,成为第一道没人AC的题 今天学的迷迷糊糊吧,总结也写不来,状态转移方程也不知道从哪下手。 把感想记下来,以后好好补dp吧 Catching Cheaters 这题不难(前提是要找到状态转移方程) dp[i][j]表示在a中取前i个组成一个子串a‘,b中取前j个组成一个子串b’,求a‘和b’的最大score 有1)(a[i]==b[j]时)dp[i][j]=(dp[i-1][j-1] +
2021-01-27 23:07:27
135
原创 贪心
贪心有一个出发点:分清什么是必须要的,什么是能贪的。这样思考能简化一些题目 如 FishingMaster 这道题我想了很久,一直在做分类讨论,题目就搞得很复杂。其实我们仔细观察,就会发现,无论如何,捕第一条鱼的时间是必须的,煮鱼的时间是必须的,在这方向上,我们再判断是否需要加上额外的捕鱼时间(煮鱼时间很短),也就想到了对煮鱼之后抓鱼之前的空闲时间排序,答案也就有了 #include <cstdio> #include <algorithm> using namespace std;
2021-01-26 22:45:37
131
1
原创 线段树
感觉学长已经讲的很好了,但听完还是迷迷糊糊的,看着别人的模板好多遍,才初步对线段树有点感觉。深入的了解也不多,写一份模板吧。 struct SegmentTree{ int l,r;//指针域 int data,sum;//数据域,以sum为例 }nodes[MAX_N]; void push_up(int pos){ nodes[pos].sum = nodes[pos << 1].sum + nodes[pos << 1 | 1].sum; } void build(i
2021-01-25 22:51:16
90
原创 使用链式向前星存图//静态链表
关键在于搞懂,head和edge数组存的都是边的编号 int pos=0;//用来给链表标号 struct node{ int to;//边的另一端点v,u端点为edge数组的下标 int val;//数据域 int next;//下一条边的编号 } edge[MAX_N];//注意MAX_N的取值 int head[MAX_N];//head数组表示以index为下标的点,pos编号最大的边 //初始化 void init(){ pos=0; for(int i=0;i<MAX_N;i+
2021-01-24 22:50:10
137
原创 拓扑排序用广搜&队列的应用
HDU3342 legal or not 拓扑排序,每当拿掉一个入度为0的点后,这个点将不会被再次使用。符合队列的出队性质。没出队一个令sum++,若有环存在则sum<n;而sum=n时满足拓扑序 本来想的是while(1)的结构,将用过的点用used数组存,接下来要用的点放在now变量中,搞到最后绕的自己头都晕了。 #include <cstdio> #include <vector> #include <cstring> #include <algorit
2021-01-23 21:00:47
194
原创 二分查找的应用
最大的最小值,最小的最大值用二分 这个发现缘起于两段看似相同的代码 这两段代码看似相同,实则大有学问 我编了一个简单的题目:在1,2,3,三个数中找到大于等于2的最小值 这是一个求最小的最大值的问题,按道理来我们要用左开右闭的区间(及靠上方的代码去逼近答案),若用靠下方的代码(左闭右开的区间)则步骤如下: 1 l=1,r=3, mid=2符合条件,执行l=mid=2; 2 l=2,r=3, mid=2符合条件,执行l=mid=3; 循环结束,但我们最后得到的l显然不是正确答案 由此发现两种方法的区别 思考
2021-01-22 21:54:16
96
原创 关于并查集扩展域问题的一些小思考
POJ1182 食物链 并查集的性质:并查集擅长维护许多具有传递性得关系 此处用扩展域做; 开三倍数组,1-n为同类域(self),n+1-2n为捕食域(eat),2n+1-3n为敌人域(enemy),先上AC代码 #include <iostream> #include <cstdio> using namespace std; const int MAX_N = 5e4+10; int fa[3*MAX_N]; int find(int x) { if(fa[x] == x
2021-01-21 22:12:57
168
1
原创 stl自定义排序方式
priority_queue 看病要排队. include <bits/stdc++.h> using namespace std; const int MAX_N=1e5; struct node{ int index; int value; } ; struct cmp{ bool operator()(node q,node p){//与sort的cmp函数不同,priority_queue左边为p右边q if(p.value!=q.value) return p.valu
2021-01-20 18:14:03
276
原创 素数筛法
素数筛法 欧拉筛,是已知的最快筛法了。时间复杂度O(n) 进一步优化的话可以考虑去掉fill函数 #include<bits/stdc++.h> using namespace std; const int MAX_N=1e5+5; int prime[MAX_N]; bool isPrime[MAX_N]; void solve(){ int size=0; fill(isPrime,isPrime+1+MAX_N,1); for(int i=2;i<=MAX_N;i++){
2021-01-17 21:36:02
72
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人