- 博客(49)
- 收藏
- 关注
原创 树链剖分笔记
什么是树链剖分?树链剖分有什么作用?字面意思,就是把一颗树拆成几个链,这些链上的节点序号是连续的,那么对于树上的路径的一些问题就可以转化为区间问题,就可以用熟悉的一些数据结构来维护了一些需要知道的定义重/轻 儿子:对于父节点来说,他的儿子节点中size最大的就是重儿子其他都是轻儿子,如果所有儿子节点size都相同,那么任意选一个作为重儿子重/轻边父节点与他重儿子连的边是重边,其余是轻边重/轻链,重边连起来的就是重链推出的性质1.如果u与v是一条轻边,那么size[v]*2<size[u]
2021-11-04 15:07:40 265 1
原创 初涉组合数
组合数 CNMC_{N}^{M}CNM二项式定理(a+b)n=∑i=0n\sum_{i=0}^n∑i=0nCniC_{n}^{i}Cniaib(n-i)证明:1.数学归纳法(就不进行这个方法的证明了)2.展开为(a+b)∗*∗(a+b)∗*∗…∗*∗(a+b),对于每一项只有两个选择是a或者b,当我们假定选择了i个a时,就需要选择n−-−i个b,然后根据组合数,只需要选择任意i个a的组合就可以,得证一些简单的性质1.CNMC_{N}^{M}CNM=n(n−1)...(n−m+1)m(m−
2021-10-21 23:31:39 208
原创 数论分块
数论分块+两道简单的例题作用:可以在On\sqrt{n}n的时间复杂度求出以下式子的值:∑i=1n\sum_{i=1}^n∑i=1n⌊\lfloor⌊ni\frac{n}{i}in⌋\rfloor⌋证明传送门题意:输入n与m,输入∑i=1n\sum_{i=1}^n∑i=1nm%i分析:m%i=m-⌊\lfloor⌊mi\frac{m}{i}im⌋\rfloor⌋ ×\times× i所以可以化简结果为m×\times×n-∑i=1n\sum_{i=1}^n∑i=1n⌊\lfloor
2021-10-20 23:39:01 250
原创 数学知识入门
定理1算术基本定理:任何大于1的正整数都可以唯一分解为有限个质数的乘积N=p1c1p2c2…pmcm质数试除法判断质数时间复杂度 O(n\sqrt{n}n)证明:为什么可以只判断到根号n?如果a小于等于n\sqrt{n}n,同时a是n的因子,那么对应的n/a是大于等于n\sqrt{n}n的,所以只需要判断小于的那部分即可代码bool isprime(int x) { if (x < 2) return false; for (int i = 2; i <=
2021-10-20 00:08:31 564 1
原创 ICPC网络赛第一场----D Edge of Taixuan
题意:每次将l到r范围内的所有点加一条长度为val的值(可以重边)然后删掉一部分边,使得1到n联通,问删除的边和最大思路:区间覆盖问题,首先判断能否到达终点,其次对边先进行降序排序,对于修改区间l到r的操作可以认为是修改l到r-1的值,每个点的值代表的是这个点到后一个点的距离,然后用所有边的和减去最终得到的和即为答案代码:#include<bits/stdc++.h>#define x first#define y second#define mm(x) memset((x),si
2021-09-22 15:11:23 215
原创 P6278 [USACO20OPEN]Haircut G题解
题目链接:传送门一丢丢思维+bit题意:给一个数组,每次将数组中大于x得值替换为x,求逆序对思路:当把比x大得数全部替换为x之后求得逆序对是原数组中小于x得值得逆序对得数量加起来,所以用一个数组预处理一个比x小得所有的逆序对的数量,修改到某一位时,前缀和就可以了代码#include <bits/stdc++.h>using namespace std;#define int long longconst int N = 1e5 + 10;int a[N], b[N];in
2021-09-12 14:51:42 242
原创 Codeforces Round741
A:传送门思路:当a小于b的一半的时候,那么最大的结果就是b%(b/2b+1)当a大于b的一半,最大值就是b%a代码:#include<bits/stdc++.h>using namespace std;int t,a,b;int main(){ cin>>t; while(t--) { cin>>a>>b; if(a<=b/2)cout<<b-b/2-1<&l
2021-08-27 17:32:17 190 1
原创 每日一题QAQ
cf736D思路:a%m=n同时b%m=n(m>=2)可以推出gcd(a,b)!=1可以直接双指针来做,不过可能代码会写出锅由于数组是静态的不会变化,可以考虑使用st表来维护代码:#include <bits/stdc++.h>#define ll long longusing namespace std;const int N = 2e5 + 10;ll c[N], a[N];ll f[N][65];int t, n;void init(int n){
2021-08-21 00:35:21 112
原创 CF739 A-E
A:传送门思路:数据范围比较小,直接存结果就好了代码#include <bits/stdc++.h>using namespace std;vector<int> q;void first(){ for (int i = 1; i < 10000; i++) { if (i % 3 == 0) continue; if (i % 10 == 3) continue;
2021-08-19 21:56:48 132
原创 洛谷P1966火柴排队
传送门思路:(ai-bi)^2 = ai^2 +bi^2 -2aibi,ai^2和 bi^2都是准确的值,要求最小值,只需要求2*ai *bi的最大值对于两个数列,存在规律 :有序 * 有序 > 无序 * 无序 ,所以只需要将两个数组的大小位置都按照一一对应,得到的结果就是最终所求由于每次只可以交换相邻的数,所以也就是求逆序对代码#include<bits/stdc++.h>using namespace std;const int N=1e5+10,mod=1e8-3
2021-08-04 00:27:43 132
原创 AcWing第五场周赛
第一题:调整数组传送门思路:只需要保证所有元素都是偶数或者都是奇数就可以ac代码#include<bits/stdc++.h>using namespace std;const int N=105;int main(){ int t; cin>>t; while(t--) { int n; cin>>n; int num[105]; for(int i=0;i&
2021-06-26 22:29:48 177
原创 CSP-2020 直播获奖
大水题(bushi 思路:新学到的一个骚东西,对顶堆(x)????堆(√)构建一个大根堆,一个小根堆,每次根据人数控制小根堆的大小如果输入数据大于小根堆的堆顶,就push到小根堆,反之就push到大根堆AC代码#include<bits/stdc++.h>using namespace std;priority_queue<int>ans1;priority_queue<int,vector<int>,greater<int>>
2021-06-20 23:45:38 618
原创 最短哈密顿路径 最短Hamilton路径
链接传送门状压dp我对状态压缩的理解:把当前的情况,转化为一个二进制数(或许有其他形式?暂时还没见到),用二进制的0和1来代表当前的情况AC代码#include <bits/stdc++.h>using namespace std;const int N = 20, M = 1 << N;int dp[M][N]; //一维代表的是当前的状态,二维代表的是最后一个到达的点是nint w[N][N];int n;int main(){ cin >
2021-06-15 10:48:45 736 2
原创 Parsa‘s Humongous Tree(树型dp)
第一次自己摸出来dp的转移方程,原来之前同学并没有凡尔赛,这个题确实是一个水题(大雾)先看一下状态转移方程f[x][0]+=max(abs(w[x][0]-w[j][0])+f[j][0],abs(w[x][0]-w[j][1])+f[j][1]);f[x][1]+=max(abs(w[x][1]-w[j][0])+f[j][0],abs(w[x][1]-w[j][1])+f[j][1]);代表的是x这个节点,可以选择左端点或者右端点两中情况,不需要考虑中间的范围,推一下会发现这两个端点就包含了所有
2021-06-14 20:46:28 240
原创 HDU-1028题解
一千个人,就有一千个状态转移方程方法一:当成完全背包问题进行求解f[i][j]=f[i-1][j]+f[i-1][j-i]+f[i-1][j-2*i]+.............f[i][j-i]= f[i-1][j-i]+f[i-1][j-2*i]+...............推出状态转移方程f[i][j]=f[i-1][j]+f[i][j-i]然后像完全背包一样转化为一维f[j]=f[j]+f[j-i]ac代码#include <bits/stdc++.h&g
2021-06-14 13:11:08 265 2
原创 A-B Palindrome 模拟
思路很简单就是纯模拟,一些边边角角需要注意一下需要特判是奇数还是偶数长ac代码#include<bits/stdc++.h>using namespace std;int t;int a,b;const int N=400005;int main(){ cin>>t; while(t--) { char s[N]; cin>>b>>a; memset(s,0,sizeo
2021-06-08 22:41:02 107
原创 2021四川省赛B Hotpot
注意规律,每2n项是一个循环,经历2n次之后就会回到初始状态ac代码#include<bits/stdc++.h>using namespace std;typedef struct sm{ int x; int y;}mms;const int N=1e5+10;int cnt[N];int n,k,m;int main(){ int t; cin>>t; while(t--) { mms ans[
2021-06-03 21:16:33 775 2
原创 最大异或对--Trie
最大异或对看到这题一瞬间想到的就是两层循环暴力,就像y总说的,很顺利地tle首先要了解异或对是怎么求的比如两个二进制数 1001 和0101 这两个数进行异或得到的结果是1100两个数二进制下对应的如果相等就是0,不相等就是1就有了思路,从最高位开始,每次尽量选择不一样的,这样的到的数就是最大的AC代码#include<bits/stdc++.h>using namespace std;const int N=31*1e5+10;const int M=1e5+10;int
2021-05-20 21:09:51 158
原创 背包问题总结
背包问题,最经典的dp首先动态规划问题,我们需要考虑的有两点,1是状态表示,2是状态计算。状态表示f[i,j]:首先是一个集合,只考虑前i个物品,且总体积不大于j的所有选法,然后集合的属性这里以最大值表示状态计算:集合的划分,也就是状态转移方程的求解01背包顾名思义,01的意思是指每个物品可以选择的次数为0或者1,选到第i个物品的时候,就可以往前推选择第i-1个物品的情况,如果第i个物品没有选,那么选择第i-1个物品的时候体积也是j,也就是f[i][j]=f[i-1][j],如果第i个物品选了,那
2021-05-19 23:28:45 595 6
原创 AcWing每日一题3510
最长公共子序列(一看这个名字这不就是LCS板子嘛,这不是有手就行然后数据1e6,成功tle自己想确实没想出来,看了y总讲解,恍然大悟lcs与lis的相互转化y总思路:1.第一个序列中是没有重复元素的,所以第二个序列中的元素如果存在于第一个序列中,它只会有一个对应的索引比如n=5第一组序列 1 2 3 4 5第二组序列 1 2 3 5 4第二组序列在第一组中存在的位置 1 2 3 5 4那么这个题就可以
2021-05-14 20:44:44 205
原创 HDU1272
并查集水题(最小生成树写起来应该更简单,不过放在并查集专题还是写并查集写法我的思路1.最后只有一个集合判断根节点是否为12.不能有环如果对两个根节点一样的元素加路径就会形成环3.不是所有的数据都出现过,找到输入的最小,和最大,然后出现的数据标记一下4.这个题直接输入0 0也是yes,看了别人的提醒改了这里就对了就是一个很基础的考验并查集板子的问题,放心大胆写ac代码#include<iostream>#include<set>#include<algor
2021-05-11 18:56:08 135 2
原创 HDU4334
注意数据 longlong一共五组数据,五重循环应该是不行(不会写然后可以分解一下问题,分成三组数据12合并为一组,34合并为一组;代码#include <iostream>#include <string.h>#include <algorithm>#define mm memset#define ll long longusing namespace std;int t;int n;const int N = 200 * 200 + 10;
2021-05-04 21:09:30 82
原创 LCS板子
#include<bits/stdc++.h>using namespace std;const int maxlen=100;char s1[maxlen],s2[maxlen];int n;int len[maxlen][maxlen];int chr[maxlen][maxlen];void getlen(){ len[0][0]=0; for(int i=1;i<=n;i++) { for(int j=1;j<=n;j+
2021-04-28 23:37:39 131
原创 二分优化的lis
#include<bits/stdc++.h>using namespace std;const int N=5e4+10;int len[N],num[N];int n;int mysearch(int len[],int length,int x){ int l=1; int r=length; while(l<r) { int mid=(l+r)/2; if(len[mid]>x) { r=mid; } else { l=mid+1;
2021-04-28 16:40:23 102
原创 LIS板子
好简单的dp板子#include<bits/stdc++.h>using namespace std;int main(){ int n; cin>>n; int num[105]; int p[105]; memset(num,0,sizeof(num)); for(int i=0;i<n;i++) p[i]=1; for(int i=0;i<n;i++) cin>>num[i
2021-04-25 21:50:55 108
原创 HDU1026 bfs
题目链接bfs水题(入门级别ac代码#include<iostream>#include<algorithm>#include<string>#include<string.h>#include<queue>#include<vector>using namespace std;typedef struct path{ int x; int y; int sec; int ans; vector<in
2021-04-23 18:11:12 102
原创 CF #509div3E Special Permutations(差分数组)
ac代码#include<bits\stdc++.h>using namespace std;typedef long long ll;const int N =2e5+10;ll p[N];int num[N];int n,m;void fuck(int l,int r,int w){ p[l]+=w; p[r+1]-=w;}int main(){ cin>>n>>m; for(int i=0;i<m;i++)
2021-04-22 20:23:46 179
原创 HDU-1556题解
水题差分数组ac代码(注意那个输出格式#include<iostream>#include<string.h>using namespace std;int n;int a[100005],p[100005];int x,y;int main(){ while(cin>>n&&n) { memset(a,0,sizeof(a)); memset(p,0,sizeof(p));
2021-04-19 20:23:23 101
原创 Yet Another Dividing into Teamst题解
先对输入的数据进行排序,用stack或者queue开个数组(这个关系不大,找个存数据的容器就好,开一个数组存放容器的数组的第一个元素一定是排序好的最小那个,然后就给输入的数据走一次就好了,代码#include<bits\stdc++.h>using namespace std;int main(){ int t; cin>>t; while(t--) { int n; cin>>n;
2021-04-17 23:09:10 145
原创 CF-1234C题解
思维题(也没啥很难想的地方,不要想太复杂直接模拟就好代码#include<bits\stdc++.h>using namespace std;int main(){ int t; cin>>t; while(t--) { int len; cin>>len; string s[2]; cin>>s[0]; cin>>s[1];
2021-04-17 22:42:23 406
原创 POJ2251
bfs代码#include<iostream>#include<queue>#include<string>#include<cstring>using namespace std;char maze[35][35][35];int bol[35][35][35];int dx[6]={1,-1,0,0,0,0};int dy[6]={0,0,1,-1,0,0};int dz[6]={0,0,0,0,1,-1};int l,r,c;i
2021-04-16 14:57:10 60
原创 POJ1321题解
kuangbin巨巨第一题棋盘问题代码#include<iostream>#include<string>#include<string.h>using namespace std;int n,m;char maze[10][10];int bol[10];int sum;void search(int cur,int tot)\\重难点讲解在下边;{ if(tot==m){ sum++; return ; } i
2021-04-16 13:24:10 162
原创 HDU--2612题解
题目链接find a way题意:两个人找武器(武器有很多),问两人到达那一把武器上所需要的时间最短,最短时间是多少,每移动一步的消耗为11思路最短问题,bfs从两人的起点各进行一次bfs一个score数组,记录有武器的地方的二人消耗时间相加,mp数组记录是否走过此位置易错点:每次之前都要将数组重新赋值,初始化为0最后求最小步数判断条件是,不能以该地方是否有武器判断,因为有武器不一定能走到比如.#.#@#.#.判断条件应该是以此处的score数组不为0判断ac代码如下#inc
2021-04-13 22:17:33 248
原创 UVA-101题解
题目链接UVA–101题意:根据不同的命令移动命令一共有四种组合可以发现一些规律第二个字符串是onto时,b需要先归原位,over则不需要第一个字符串是move时,a,需要先归位,pile则不需要最后一步就是进行的转移思路:vector代码如下#include<bits\stdc++.h>using namespace std;vector<int>ans[105];int n;int x,y;string s1,s2;void find(int a,
2021-04-13 14:15:29 329
原创 POJ-3984题解
第一个不看题解就自己ac的题好耶思路 bfs+动态数组存坐标(这里没想到其他办法,如有更优望告知要注意一下那个输出的时候括号那里的空格,错了两次才看出来ac代码#include<bits/stdc++.h>using namespace std;bool maze[5][5];typedef struct path{ int x; int y; int number; vector<int>loc;}Path;queue<P
2021-04-08 23:07:02 96
原创 KMP
直接上代码,作者是看b站视频学会的,附上链接一遍不会就多看几遍总能看会的(这个是作者觉得讲的最清晰的#include<iostream>#include<string>#include<cstring>using namespace std;const int maxlen=10005;char s[maxlen],p[maxlen];int nxt[maxlen];int n,m;void kmp(){ nxt[0]=0; int
2021-03-31 23:07:11 88
原创 HDU-2546
先上代码再说我看了其他大佬的题解后的理解#include<iostream>#include<algorithm>#include<string.h>using namespace std;const int maxnum=1050;int n;int m;int price[maxnum];int dp[maxnum][maxnum];int main(){ memset(price,0,sizeof(price)); memset
2021-03-29 23:41:45 119
原创 HDU-2602题解(二维dp
最简单的01背包直接上代码(二维dp#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>using namespace std;int w[1005],v[1005];int n;int bags;int dp[1005][1005]; int t;int main(){ cin>>t; while(t--)
2021-03-29 22:57:40 332
原创 01背包问题
最简单动态规划也要了好久才学会,菜狗无疑先上代码来说我的理解思路(暂时只写出来了二维的dp;#include<iostream>#include<cstdio>#include<algorithm>using namespace std;const int Mnums=10005;int w[Mnums],v[Mnums];int n;int bags;int dp[Mnums][Mnums];int main(){ while(~scan
2021-03-29 12:55:51 53 1
原创 HDU-3068
ac代码#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int N=110005;char s[N*2+10],str[N*2+10];int p[N*2+10];int n,m;void manacher(){ int mid=0; int rt=0; int ans=0
2021-03-28 22:10:12 50
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人