10 2015 档案
摘要:取M=√300000。设g[i]表示程序员的mod最小的值。若$Yconst int N=300010,M=550;int n=300000,m=n/M,q,i,x,pos[N],st[M],f[N],tag[M],g[M];char op[5];inline voi...
阅读全文
摘要:考虑离线操作,求出每个向量存在的时间区间,用时间线段树来进行分治,在每个节点求出凸壳后,询问时在凸壳上三分答案。时间复杂度O(n\log^2n)。#include#includetypedef long long ll;const int N=200010,M=4000000;int n,m,i...
阅读全文
摘要:首先对b串做kmp求出nxt数组。设f[i][j]表示考虑了a的前i个字符,在b中匹配到了j的最长长度,按照kmp算法直接转移即可。ans=n-\max(f[n][j])。时间复杂度O(nm)。#include#include#define N 1010char a[10010],b[N];...
阅读全文
摘要:首先求出SCC,把图缩点成一个DAG。通过拓扑排序+DP求出:dp0[x]:从x点出发能到的点的集合。dp1[x]:能到x的点的集合。对于一条边x->y,将它改为双向边后,形成的新的SCC的点数为dp0[x]&dp1[y]中1的个数,用bitset维护。时间复杂度$O(\frac{n^3}{32})...
阅读全文
摘要:若[0,i]的数都可以得到,那么[1,所有不大于i+1的数的和]的数都可以得到。如此暴力枚举答案,用可持久化线段树支持查询,因为每次数字至少翻一倍,所以复杂度为O(m\log^2n)。#include#includeconst int N=100010,M=1800000;int n,m...
阅读全文
摘要:离线算法:先将所有涉及到的串建成字典树,然后用线段树维护dfs序,时间复杂度O(m\log L)。在线算法:用替罪羊树动态维护Trie树的dfs序即可,时间复杂度O(L\log L)。#include#include#includeusing namespace std;const int ...
阅读全文
摘要:首先通过不断翻转坐标系,假设三个点以横坐标为第一关键字,纵坐标为第二关键字排序后A在B前面,B在C前面。那么只需要处理以下两种情况:1.B的纵坐标在AC之间,这时三个点的距离和为2((x_C+y_C)-(x_A+y_A))。可以用线段树处理出每个点作为B时x_A+y_A以及x_C+y_C...
阅读全文
摘要:整体二分+树状数组套Treap,时间复杂度O(n\log^3n)。#include#include#include#define N 100010using namespace std;int n,m,tot,i,X0,Y0,X1,Y1,cq,bx[N],by[N],bz[N],ans[N],t...
阅读全文
摘要:设f[i][j]为第i张图中j点所在连通块的编号,加边时可以通过启发式合并在O(dn\log n)的时间内维护出来。对于每个点,设h[i]为f[j][i]的hash值,若两个点hash值相等,则它们在d张图中均连通。#includetypedef unsigned long long ll;co...
阅读全文
摘要:树的点分治,将点分治的过程记录下来,每一个分治结构按到分治中心的距离维护所有点。对于一个点二分答案,然后在O(\log n)个分治结构中二分查找,时间复杂度O(n\log^3n)。#include#includeconst int N=50010,M=1000010;int n,m,i,x,...
阅读全文
摘要:考虑将序列分成\sqrt{n\log n}块,每块维护下凸壳,修改时在相应块打上需要修改的标记。查询时,对于两端零散部分暴力查询。对于中间的块,如果有修改标记,则暴力重构。然后在凸壳上查询时不断把小于T的左端点踢出,那么最后如果凸壳上还有点,那么左端点一定\geq T。时间复杂度$O(m...
阅读全文
摘要:建立线段树,每个节点维护该区间内的最优线段。插入线段时,在线段树上分裂成O(\log n)棵子树,若与当前点的最优线段不相交,那么取较优的,否则暴力递归子树。查询时在叶子到根路径上所有点的最优线段中取个最优的即可。时间复杂度O(n\log^2n)。#include#include#inclu...
阅读全文
摘要:如果S==T,那么答案为0。如果S与T不连通,那么答案为inf。否则,S到T的最短路径上至少有一条边。求出以S为源点的最短路图,是个DAG,随便抓一条S到T的最短路,记为P。设dpS[x]表示在这个图上,能到达x点的离S最近的在P上的点,可以通过拓扑排序+DP求出。然后求出以T为源点的最短路图,在T...
阅读全文
摘要:把集合A[i]看作i点的前驱点集合,建成一个DAG,并新建超级源S,向每个前驱集合为空的点连边,那么B[i]就是S到i的必经点集合。首先使用Lengauer-Tarjan算法建立出以S为起点的Dominator Tree,那么B[i]就是i在树上的所有祖先。对于一个询问,构造出虚树,然后统计虚树上每...
阅读全文
摘要:离散化后通过树状数组求出:b[i]为i之前比它小的。c[i]为i之前比它大的=i-1-i之前小于等于它的。d[i]为i之后比它小的。e[i]为i之后比它大的=n-i-f[i]。f[i]为i之后小于等于它的。则:cnt_{123}=\sum_{i=1}^n b[i]e[i]$cnt_{321}=\...
阅读全文
摘要:一维的情况:排序后维护一个单调指针即可,时间复杂度O(n\log n)。二维的情况:旋转坐标系后转化为二维数点问题,扫描线+树状数组维护即可,时间复杂度O(n\log n)。三维的情况:将后两维旋转坐标系,对于每个x,预处理出横坐标为x的点的后两维的二维前缀和。枚举一个点,再枚举另一个点的x...
阅读全文
摘要:设a[i][j]表示(i,j)右下角要增加多少aj[i][j]=a[i][j]\times jai[i][j]=a[i][j]\timesiaij[i][j]=a[i][j]\timesi\timesj则查询(x,y)左上角内的权值和时,答案$=(x+1)(y+1)ask_{...
阅读全文
摘要:将输入的Trie建成AC自动机,并建出fail树。那么操作1等价于在给定点的子树的并集里都加1。操作2等价于查询给定点到根节点路径的并集的权值和。求出DFS序后,对于操作1,将点按进入时间戳从小到大排序,然后求出并集,进行区间修改即可。对于操作2,构造给定点集的虚树,在虚树的每一条边上询问权值和,累...
阅读全文
摘要:对于一个连通块,取一个点进行dfs,得到一棵dfs搜索树,则这棵树的深度不超过10,且所有额外边都是前向边。对于每个点x,设S为三进制状态,S第i位表示根到x路径上深度为i的点的状态:0:选了1:没选,且没满足2:没选,且已满足设f[i][j]表示考虑根到x路径上深度为i的点时这些点的状态为j时的最...
阅读全文
摘要:先不断将度数小于D的点都删去,再找到剩下的图里最大的连通块即可。#include#include#define N 200010int n,m,D,x,y,i,g[N],v[N='0')&&(c='0')&&(cans)for(ans=t,x=1;x1)std::sort(fin+1,fin+ans...
阅读全文
摘要:斐波那契数列模10^m的循环节为6\times10^m,于是从低位到高位dfs即可。#include#include#define N 20typedef long long ll;typedef unsigned long long ull;int n,i,flag;char a[N];l...
阅读全文
摘要:每个点的最优取值范围是一个区间,将叶子一层层剥去,得到一棵有根树,父亲的取值范围由儿子推得,时间复杂度O(n\log n)。#include#include#define N 500010int n,m,i,j,x,y,c,g[N],v[N='0')&&(c='0')&&(c0?x:-x;}in...
阅读全文
摘要:第i轮,a[i%n]+=b[i%m]。枚举i,计算它变为0的次数,假设为t,那么有t=i+kn。对于所有的i和k,(i+kn)%m形成了若干个总长度为m的环。对于每个a[i],先在环中求出一轮最多可以减少多少,以及一轮的增量是多少,由此可以求出在几轮后变为0。再在前缀后缀分类讨论一下即可求出具体是在...
阅读全文
摘要:首先在开头加上-inf,结尾加上inf,最后答案减2即可。设s[i]为i之前未知的个数,f[i]为以i结尾的LIS,且a[i]已知,那么:f[i]=max(f[j]+min(s[i]-s[j],a[i]-a[j]-1))+1,其中j#includeusing std::sort;const int ...
阅读全文
摘要:假设询问两点中d[x]#include#define N 200010using namespace std;int n,m,q,i,op,x,y,T,pos[N],bit[N],ans[N],cb,cc;int g[N],v[N],nxt[N],ed,f[N],size[N],son[N],top...
阅读全文