07 2021 档案

摘要:给出一个初始为0的序列。 询问区间最大值,并同时支持区间修改和区间翻转。 就正常模仿线段树,给Splay打懒标记即可。 巨大的坑就是要保证虚拟节点,0,1,n+2不对答案产生影响。 这里把他们的权值和区间值全置为负无穷。 //区间修改 //区间反转 //区间求MAX #include<bits/st 阅读全文
posted @ 2021-07-31 20:50 zlc0405 阅读(43) 评论(0) 推荐(0) 编辑
摘要:给出一个数组,请你支持单点修改或询问区间第k小。 先离散化。 然后对线段树的每个节点维护一颗权值线段树。 权值线段树内存放区间内的所有点。 然后单点修改操作就是先把对应树链上的a_x全删了,然后把a_x改成y,再插入。 询问第k小就是先dfs出与这个区间有关的线段树节点。 然后在这些节点对应的权值线 阅读全文
posted @ 2021-07-29 16:33 zlc0405 阅读(54) 评论(0) 推荐(0) 编辑
摘要:给出一个序列。 每次询问区间最小的众数 强制在线 预处理出两个数组: \(a[i][j]\):表示第i个块到第j个块的最小的众数。 \(b[i][j]\):表示前i个块中值j出现了几次,这里j需要先离散化。 预处理出a数组和b数组。 预处理a:枚举i和j,用数组暴力维护同一个i的所有j的答案。(从前 阅读全文
posted @ 2021-07-29 15:55 zlc0405 阅读(31) 评论(0) 推荐(0) 编辑
摘要:题意: 给一棵树,每条边有权,求一条简单路径,使得权值和等于k且边权最小。 题解: DSU on Tree裸题,合并的时候套个map就行。注意慎用Splay,Splay常数巨大,并且感觉好像复杂度并不是均摊的。 #include<bits/stdc++.h> using namespace std; 阅读全文
posted @ 2021-07-28 18:38 zlc0405 阅读(50) 评论(0) 推荐(0) 编辑
摘要:树链剖分 对树上的一条链加$12,22,...n^2$。 每次询问单点。 我们设L是u和v的LCA。 那么对于链u->L,区间加上$(dep_u-dep_x+1)^2$。 即加上$(dep_x-dep_u-1)^2$ 对于链L->v,区间加上$(dep_u-dep_L+1+dep_x-dep_L)^ 阅读全文
posted @ 2021-07-23 18:58 zlc0405 阅读(103) 评论(0) 推荐(0) 编辑
摘要:题意: 给出一个序列。 每次询问一个区间内有多少个不同的数异或a<=b。 题解: 首先有个前置知识,就是不带区间的情况下有多少个不同的数异或a<=b,这是一个经典的字典树上DP的模型,找到对应的子树统计信息即可,这里不再赘述。 然后考虑区间,如果把不同的数这个条件去掉,可以直接上可持久化字典树。 但 阅读全文
posted @ 2021-07-23 15:17 zlc0405 阅读(139) 评论(0) 推荐(1) 编辑
摘要:区间开平方直接上暴力即可。 因为一个数开几次就到1了。 维护一个区间最大值,当该区间最大值是1的时候直接return。 复杂度O(nlognlogn)? #include<bits/stdc++.h> using namespace std; const int maxn=1e5+100; int 阅读全文
posted @ 2021-07-21 20:24 zlc0405 阅读(32) 评论(0) 推荐(0) 编辑
摘要:前置结论:给出n个点,选择一个点p使得这个n个点到p的距离之和最小。 那么这个p一定是中间两个点的线段或中间一个点。 基于这个结论,考虑用线段树维护区间点权和和区间点权乘坐标的和。 然后对每个区间询问,二分出p的位置,对p之前和p之后的区间分类计算。 修改操作就是毒瘤离散化+模拟。 #include 阅读全文
posted @ 2021-07-21 20:22 zlc0405 阅读(35) 评论(0) 推荐(0) 编辑
摘要:暴力枚举两个端点,BFS算偏心距。 有O(n)的做法,跪了 #include<bits/stdc++.h> using namespace std; const int maxn=305; vector<pair<int,int> > g[maxn]; int n,s; int vis[maxn], 阅读全文
posted @ 2021-07-21 16:22 zlc0405 阅读(40) 评论(0) 推荐(0) 编辑
摘要:有一个数列,初始值均为0,他进行N次操作,每次将数列[ai,bi)这个区间中所有比Hi小的数改为Hi,他想知道N次操作后数列中所有元素的和。 //每次把比Hi小的数改成Hi //把所有询问按Hi从小到大排序 //暴力修改即可 #include<bits/stdc++.h> using namespa 阅读全文
posted @ 2021-07-21 16:21 zlc0405 阅读(49) 评论(0) 推荐(0) 编辑
摘要:对于一个给定的序列a1, …, an,我们对它进行一个操作reduce(i),该操作将数列中的元素ai和ai+1用一个元素max(ai,ai+1)替代,这样得到一个比原来序列短的新序列。这一操作的代价是max(ai,ai+1)。进行n-1次该操作后,可以得到一个长度为1的序列。 我们的任务是计算代价 阅读全文
posted @ 2021-07-21 14:59 zlc0405 阅读(55) 评论(0) 推荐(0) 编辑
摘要:题意简述:给定n个点排成一排,每个点有一个点权,多次改变某个点的点权并将最大点独立集计入答案,输出最终的答案 定义f(i,0)为第i个数不取,定义f(i,1)为第i个数取。 转移式子: f(i,0)=max(f(i-1,0),f(i-1,1)) f(i,1)=max(f(i-1,0)+a[i]) 可 阅读全文
posted @ 2021-07-21 14:56 zlc0405 阅读(47) 评论(0) 推荐(0) 编辑
摘要:基础点分治。 点分治的模板基础上改一下即可。 询问树上长度模数是3的路径 //询问有多少路径的长度加起来是3的倍数 #include<bits/stdc++.h> using namespace std; const int maxn=2e5+10; int n; vector<pair<int,i 阅读全文
posted @ 2021-07-20 13:57 zlc0405 阅读(33) 评论(0) 推荐(0) 编辑
摘要:每个节点上开一个cnti数组表示i这个数字出现了多少次,那么节点i上出现最多的数字就是cnt数组的最大值。 然后每次的操作可以调整为: 在u v上打一个+1的标记,在uv的lca上打一个-1的标记,在lca的父亲上打一个-1的标记。 然后打完标记后从叶子开始启发式的向上合并。 假设当前节点是u。 首 阅读全文
posted @ 2021-07-16 20:43 zlc0405 阅读(33) 评论(0) 推荐(0) 编辑
摘要:诸神眷顾的幻想乡 给出一棵树 叶子节点<=20 询问树上一共可能有多少个不同颜色序列 颜色值域<=10 这题有一个结论 从树的所有叶子节点为根开始搜,搜到的从根到节点的路径 包含树上所有叶子的路径 观察到叶子节点的数量<=20 那么就可以以每个叶子节点为根搜索,把搜到的路径 依次插入同一颗字典树内 阅读全文
posted @ 2021-07-15 23:44 zlc0405 阅读(35) 评论(0) 推荐(0) 编辑
摘要:研究了下概念,就学会了基于字典树的广义SAM构造方法。 北大带哥提出的别的高效构造完全不会了... SAM是基于字符串的,GSAM就是把lst换成字典树的上一个节点就行了。 #include<bits/stdc++.h> using namespace std; const int maxn=3e6 阅读全文
posted @ 2021-07-15 23:22 zlc0405 阅读(49) 评论(0) 推荐(0) 编辑
摘要:首先对每个位置处理出它作为右端点的最长子序列zz[i] 这个问题是老题 然后,每次区间询问就是求 max(i-max(l,i-zz[i]+1)+1) 这里注意到,i-zz[i]+1这玩意好像是单调不减的? 尝试证一下... 那么可以二分区间内第一个i-zz[i]+1大于l的位置p p前面半段的答案稳 阅读全文
posted @ 2021-07-15 21:26 zlc0405 阅读(49) 评论(0) 推荐(0) 编辑
摘要:对于t=0的情况: 在不同位置出现的子串算同一个子串,这里巨大的坑点是要把后缀自动机上除起点以外的所有点的sz置为1(不管它是虚拟节点还是真实节点),这一点萌新还没理解... 然后把所有节点按照len值从小到大排序,然后做一个倒着的转移,每个节点首先能转移出sz个子串,然后加上它后继节点的贡献,可以 阅读全文
posted @ 2021-07-15 20:12 zlc0405 阅读(41) 评论(0) 推荐(0) 编辑
摘要:给出一个序列,每次询问区间内出现次数恰好是k的元素个数。 //c[maxn]维护出现i次的数有多少 //cc[maxn]维护第i个数出现多少次 //然后莫队 #include<bits/stdc++.h> using namespace std; const int maxn=4e4+100; in 阅读全文
posted @ 2021-07-15 18:48 zlc0405 阅读(46) 评论(0) 推荐(0) 编辑
摘要:给出一个字符串。 请你找出所有出现次数恰好为k次的子串中,出现次数最多的子串长度。 先建出后缀自动机。 每个节点所代表的子串长度区间为len[link[i]]+1到len[i]。 每个节点所代表的子串出现次数是它的link树子树大小, 用差分数组维护一下。 //一个子串的出现次数= //它的link 阅读全文
posted @ 2021-07-15 16:21 zlc0405 阅读(24) 评论(0) 推荐(0) 编辑
摘要:支持在一个字符串后面在线添加一个字符,同时每次询问当前字符串的本质不同子串数量。 后缀自动机好像有一个性质,就是在线添加字符的时候并不会影响link树的形态,只是在link树上新增一个节点?刚开始一知半解... #include<bits/stdc++.h> using namespace std; 阅读全文
posted @ 2021-07-15 15:41 zlc0405 阅读(31) 评论(0) 推荐(0) 编辑
摘要:建出link树后,每个节点的len[i]-len[link[i]]就是它所代表的不同子串数量。 #include<bits/stdc++.h> using namespace std; const int maxn=4e6+10; int len[maxn],link[maxn],nxt[maxn] 阅读全文
posted @ 2021-07-15 15:14 zlc0405 阅读(73) 评论(0) 推荐(0) 编辑
摘要:先对母串建立后缀自动机。 然后建出link树。 然后,在link树上算出每个节点的子树大小,子树大小*len[i]就是当前节点所表示的字符串的长度乘出现次数。 坑:后缀自动机里存在虚拟节点,这些节点的sz是0. 处理方法就是只对cur记sz[cur]=1,对clone不管。 #include<bit 阅读全文
posted @ 2021-07-14 20:22 zlc0405 阅读(52) 评论(0) 推荐(0) 编辑
摘要:给定n个字符串s1,s2,...sn q次询问,第k个字符串在s[l,r]中出现了多少次。 首先肯定是对所有的字符串建立AC自动机。 然后,考虑弱化版本,第k个字符串在所有字符串中出现了多少次。 先找到第k个字符串在字典树内对应的节点。 然后,k的整个子树所表示的字符串,k都是它们的后缀。 这样就可 阅读全文
posted @ 2021-07-13 21:44 zlc0405 阅读(143) 评论(0) 推荐(0) 编辑
摘要:有n次操作,格式为1 c或2 j c,分别表示新建一个为c的字符串,和在第j次操作得到的串后接上c后新建一个字符串。 接着是m次询问,每次询问版本i的串中,t的出现次数。 m次询问,每次询问版本i的字符串中,t的出现次数。 如果暴力建字符串肯定存不下。 考虑a aa aaa aaaa aaaaa.. 阅读全文
posted @ 2021-07-13 21:30 zlc0405 阅读(146) 评论(0) 推荐(0) 编辑
摘要:给出n个字符串。每个字符串最初的权值都是0。 请你支持以下两种操作: 1)把第i个字符串的权值改成x。 2)给出一个文本串q,询问所有字符串中,是q的子串的最大权值。 做法: 首先对所有字符串建立AC自动机。 假设所有字符串互不相同。 输入一个文本串,对于文本串的第i个节点,它到根节点的路径的权值最 阅读全文
posted @ 2021-07-13 18:07 zlc0405 阅读(51) 评论(0) 推荐(0) 编辑
摘要:给出n个字符串,每个字符串有两种状态:退役和服役 三种操作: 1)询问当前服役的字符串在询问字符串内的出现次数之和。 2)把一个退役的字符串设为服役。 3)把一个服役的字符串设为退役。 如何处理操作1? 对所有字符串建出AC自动机,建出fail树,求子树和。 每个模式串s_i在t中出现的次数之和就是 阅读全文
posted @ 2021-07-13 15:53 zlc0405 阅读(40) 评论(0) 推荐(0) 编辑
摘要:给出一个字符串t和n个字符串 设f(t,s)为s在t中的出现次数。 求$sum_^n\sum_^nf(t,s_i+s_j)$ 枚举划分点。 对t的每个划分点x,处理出有多少个字符串是当前t[0,x]的后缀。 然后反着建AC自动机,反着枚举划分点x,处理出有多少个字符串是当前t[x,n]的后缀。 处理 阅读全文
posted @ 2021-07-13 12:52 zlc0405 阅读(27) 评论(0) 推荐(0) 编辑
摘要:题目描述: 设$d(x)$为$x$的约数个数,给定$n,m$,求$\sum_^n\sum_^md(ij)$ 首先有一个前置知识: \(d(ij)=\sum_{x|i}\sum_{y|j}[gcd(x,y)=1]\) 所以原式等于: \(\sum_{i=1}^n\sum_{j=1}^m\sum_{x| 阅读全文
posted @ 2021-07-13 00:49 zlc0405 阅读(40) 评论(0) 推荐(0) 编辑
摘要:题目描述: 有一张$n \times m$的数表。 其第$i$行第$j$列(\(1 \leq i \leq n,1 \leq j \leq m\))的数值为能同时整除$i$和$j$的所有自然数之和。 给定$a$,计算数表中不大于$a$的数之和。 设$d(x)$为$x$的因子之和。 写出式子: \(\ 阅读全文
posted @ 2021-07-12 22:05 zlc0405 阅读(36) 评论(0) 推荐(0) 编辑
摘要:题意: 求$\sum_^n\sum_^m[gcd(i,j)=prime]$ 题解: 首先把$prime$换成$k$,和前几题的做法一样,可以快速推导到这一步: \(\sum_{k=1}^n\sum_{d=1}^{n/k}\mu(d)[n/kd][m/kd][k=prime]\) 然后暴力枚举每个质数 阅读全文
posted @ 2021-07-12 20:08 zlc0405 阅读(38) 评论(0) 推荐(0) 编辑
摘要:就在例题的基础上加个容斥。注意循环部分不要开long long ,时间会极大幅度的增长。 #include<bits/stdc++.h> using namespace std; const int maxn=1e5+100; typedef long long ll; int vis[maxn]; 阅读全文
posted @ 2021-07-12 13:32 zlc0405 阅读(28) 评论(0) 推荐(0) 编辑
摘要:题意: 给出$a,b,d$,求满足$1 \leq x \leq a,1 \leq y \leq b$,且$gcd(x,y)=d$的二元组$(x,y)$的数量。 \(1 \leq n \leq 5 \times 10^4\) \(1 \leq d \leq a,b \leq 5 \times 10^4 阅读全文
posted @ 2021-07-12 13:20 zlc0405 阅读(36) 评论(0) 推荐(0) 编辑