PAT甲级题库考点 共155题,基本输入输出2题,单源最短路1题,树的遍历1题1001 A+B Format 基本输入输出 1002 A+B for Polynomials 基本输入输出 1003 Emergency 单源最短路 1004 Counting Leaves 树的遍历 ...
树上差分 边权差分 将边权转化成子节点的点权,在a到b路径上边权加c等于在a和b上分别加c,在lca(a,b)上减2c,此时边权和等于子树差分和点权差分 在a到b路径上点权加c等于在a和b上分别加c,在lca(a,b)和fa[lca(a,b)]上减c,此时点权和等于子树差分和#include<iostream>#include<cstdio>#include<cstring>#include<vector>using name...
树上启发式合并 统计子树出现最多的颜色编号之和#include<iostream>#include<cstdio>#include<cstring>using namespace std;typedef long long ll;const int N=1e5+10;int h[N],con=1,nex[N*2],to[N*2];int col[N],sz[N],son[N],f,cnt[N],mc;ll ans[N],sum;void add(int a,int
点分治 #include<iostream>#include<cstdio>#include<cstring>using namespace std;const int N=1e4+10;int h[N],w[N*2],nex[N*2],to[2*N],con=1;int sz[N],ms,rt,sum;int del[N],vis[100000010],dis[N],res[N],ires,m,q[128],ans[128],gc[N],igc;void ad.
单调栈 #include<iostream>#include<cstdio>#include<cstring>using namespace std;typedef long long ll;int h[100010];int st1[100010],r1,p1[100010],m1[100010];int st2[100010],r2,p2[100010],m2[100010];int main(){ //freopen("1.txt","r",st.
线性基 将每个整数看成是一个向量,这些整数的线性基是这些整数的极大异或无关组,每个整数都能唯一的通过线性基内的数异或出来,整数直接互相异或的结果也能通过线性基异或出来,线性基的所有异或结果能通过这些整数异或出来.构造 线性基是一个一维数组,下标表示二进制位,每个二进制位对应一个线性基的整数向量. 构造时将每个整数逐个插入线性基.设插入值为x. 从高位到低位检查x,为0的位直接跳过,否则检查线性基该位是否已有整数向量,若有则将x异或该向量并跳过该位,否则有两种处理方法....
2020牛客多校第八场A All-Star Game 线段树+可撤销并查集 1.球员编号从1-n,球迷编号从1-m,有重叠部分,可以将球迷编号整体加n. 2.求最小球员个数等于求球迷的连通分量数,如果某个球迷的度为0表示没有喜欢的球员,此时无解输出-1. 3.变量con表示度为0的球迷的数量,初始值为m,用来判断是否无解,变量ans表示球迷的连通分量数,初始值为m. 4.先将初始状态直接存入map中,key为边,value为边存在的起始时间1. 5.输入修改时,在map中查询是否有这条边,如果有表示此次为删边修改,向线段树插入这条边,插入区间为这条边的存...
可撤销并查集 解决在树上加边或删边后的两点联通性问题,线段树线段表示时间,结点存储这个时间段内存在的边,线段树使用区间修改,单点查询.查询时先把每个结点储存的边的两端利用并查集合并,离开时需要利用栈进行撤销.#include<iostream>#include<cstdio>#include<cstring>#include<map>#include<vector>#include<stack>using namespace st.
线段树 单点修改 无需lazy标记,直接写,此时每个点存这个区间对应的答案.区间修改,单点查询 修改被修改区间包括的区间,查询时一路加到底.此时每个点并没有直接存这个区间对应的答案.区间修改,区间查询 需要lazy标记或者标记永久化,此时每个点不一定存的这个区间对应的答案...
__int128 inline __int128 read() { __int128 x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); } while(ch>='0'&&ch<='9') { x=x*10+ch-'0'; ch.
最小异或生成树Xor-MST 1.将每个点的权值转换成二进制,从高位往低位依次插入01字典树. 2.dfs遍历该字典树的每个结点,如果某个结点有两个子节点,这两个子节点的子树分别会构成两个连通块,要在这两个连通块之间各选一个点连边并使它们的异或值最小,通过find函数递归处理这个问题.ans还要加上此时产生的二进制位对应的值. 3.find函数中先考虑能不能同时往0子节点或同时往1子节点走,此时这两条边异或值为0,返回值取这两种走法的最小值.如果不能同时往0或往1,只能一个往1一个往0,此时...
广义后缀自动机 同时处理多个字符串的字串问题在线写法const int N=1e6+10;int len[2*N],link[2*N],tr[2*N][32],con=2,last=1;int add(int c,int last){ if(tr[last][c]) { if(len[last]+1==len[tr[last][c]]) return tr[last][c]; int ne=con++,p=last,r=tr[last][c];
后缀自动机 求本质不同的字串个数#include<iostream>#include<cstdio>#include<cstring>using namespace std;const int N=1000000+10;char s[N];int len[2*N],tr[2*N][32],link[2*N],con=2,last=1;void add(int c){ int p,now=con++; len[now]=len[last]+1;
无向图的双连通分量 无向图的双连通分量 边双连通分量 指极大的不存在桥的联通分量.去掉桥会使图不连通. tarjan算法,时间复杂度O(n+m) 1.以未建立时间戳的点为起点进行dfs,将该点压入栈中,建立该点的时间戳(f数组)并初始化从该点出发的最小的时间戳(mf数组). 2.遍历以该点为起点的所有终点,若未建立时间戳则继续进行dfs,结束后更新mf数组;否则若不为来时的边上的点,也更新mf数组.如果终点的mf值大于该点的f值,说明这条边是桥....
有向图的强连通分量 有向图的强连通分量 tarjan算法,时间复杂度O(n+m),可以有重边,自环.有向图的强连通分量是指极大联通分量,其内部所有点互相可达. 1.以未建立时间戳的点为起点进行dfs,将该点压入栈中,建立该点的时间戳(f数组)并初始化从该点出发的最小的时间戳(mf数组). 2.遍历以该点为起点的所有终点,若未建立时间戳则继续进行dfs,结束后更新mf数组;否则若在栈中,也更新mf数组. 3.递归回到该点后,该点的mf值如果等于f值表示它是一个强连通...
次小生成树 严格次小生成树1.先求出最小生成树2.枚举不在最小生成树上的每一条边,加入最小生成树构成环3.每个环上找到原来最小生成树上的最长的边和次长的边4.如果最长的边小于新加的边,将最长边去掉,否则去掉次长的边,如果次长的边等于最长的边,不存在严格次小生成树.5.求权值非严格次小生成树只需要找到原来最小生成树上的最长的边去掉即可,允许出现结果权值与最小生成树相同....
差分约束 求最小值转换成最长路,求最大值转换成最短路 最小值xi<=xj+c,出现负环无解,最大值xi>=xj+c,出现正环无解. 常数不等式xi>=c转换成xi>=c+x0,x0为超级源点. 源点需要能到达所有边....
输入整行未知个数的数据 char c; while(scanf("%c",&c)!=EOF) { int res=0; res=res*10+c-'0'; while(scanf("%c",&c)!=EOF&&c!=' '&&c!='') {res=res*10+c-'0';} r[con++]=res; ...
无穷大值 整数 memset(d,0x3f,sizeof(d)) (1061109567)浮点数 memset(d,0x42,sizeof(d)) (1.56842e+11) memset(d,0xc2,sizeof(d)) (-4.12554e+13)
二分图 染色法判断二分图#include<iostream>#include<cstdio>#include<cstring>using namespace std;const int N=1e5+10;int h[N],nex[N<<1],to[N<<1],con=1;int c[N],vis[N];int dfs(int x)//O(n+m)不含奇数环即为二分图{ vis[x]=1; int d=c[x]==1?-