zoukankan      html  css  js  c++  java
  • 年终做题记录

    (模板)后缀树

    namespace SufT {
    	int ch[N<<1][29],link[N<<1],st[N<<1],len[N<<1],now,rem,cnt,sz;
    	void init() {cnt=1,now=1,len[0]=inf;}
    	int nw(int s,int l) {st[++cnt]=s,len[cnt]=l,link[cnt]=1; return cnt;}
    	void extend(int x) {
    		sz++, rem++; int last=1;
    		while(rem) {
    			while(rem>len[ch[now][s[sz-rem+1]]]) rem-=len[now=ch[now][s[sz-rem+1]]];
    			int &v=ch[now][s[sz-rem+1]], c=s[st[v]+rem-1];
    			if(x==c||!v) {
    				link[last]=now,last=now;
    				if(!v) v=nw(sz-rem+1,inf); else break;
    			} else {
    				int u=nw(st[v],rem-1);
    				ch[u][c]=v, ch[u][x]=nw(sz,inf);
    				st[v]+=rem-1, len[v]-=rem-1;
    				link[last]=v=u, last=u;
    			}
    			if(now==1) rem--; else now=link[now];
    		}
    	}
    	void creal() {
    		rep(i,1,cnt) if(len[i]>n) len[i]=n-st[i]+1;
    	}
    	int dfs(int u,int dep,int lf=1,int res=0) {
    		rep(i,0,26) if(ch[u][i]) {
    			int v=ch[u][i]; res+=dfs(v,dep+len[v]); lf=0;
    		}
    		if(res>1) ans=max(ans,1ll*res*dep);
    		else if(lf) res=1;
    		return res;
    	}
    }
    

    (模板)广义后缀树

    https://www.luogu.com.cn/record/64216308

    LG4198 楼房重建

    全部化成斜率形式。

    考虑线段树维护区间最大值 \(g_{[l,r]}\) 和区间答案 \(s_{[l,r]}\),其中区间答案为只提取这个区间,从区间左端点向右边看,能看到区间内的楼房数。

    由于题目只有单点修改,所以我们唯一的问题在于如何 push up。

    显然 \(g\) 是容易 push up 的,考虑 \(s\)\(s\) 的结构比较特殊,导致其无法直接根据儿子节点算出。考虑在 pushup 的时候 \(O(\log n)\) 时间在子树中求解。

    (设 \(ls\) 为左儿子,\(rs\) 为右儿子)假如我们现在在计算 \(s_u\) 的值。首先 \(s_{ls_u}\) 必然包括在 \(s_u\) 里面。我们递归处理右儿子子树中的情况:

    • 设目前递归区间 \([l,r]\) (线段树上节点为 \(v\)
    • 如果 \(g_{ls_v}<g_{ls_u}\),则 \(s_{ls_v}\) 不会被包含在 \(s_u\) 中,直接递归 \(rs_v\)
    • 如果 \(g_{ls_v}>g_{ls_u}\),则 \(s_{rs_v}\) 被包含在 \(s_v\) 中的那部分会有解,即对 \(s_u\) 的贡献为 \(s_v-s_{ls_v}\)。然后递归 \(ls_v\)

    https://hydro.ac/d/bzoj/record/61b40273b6d37bd6e20ce252

    https://www.luogu.com.cn/record/64730443

    BZOJ2588 Count on a tree

    树上主席树

    主席树需要维护的东西具有可减性。树上 \(u,v\) 路径为 \(s_u+s_v-s_{lca}-s_{fa_{lca}}\)

    然后每个节点的主席树可以从父节点继承过来修改。

    https://www.luogu.com.cn/record/64958724

    https://hydro.ac/d/bzoj/record/61b732bae2b0fa8e2f76c97b

    SDOI2013 森林

    考虑如何处理合并。可以启发式处理树的合并,因为只需要维护倍增数组和修改主席树即可。

    https://www.luogu.com.cn/record/64866325

    LG7706 「Wdsr-2.7」文文的摄影布置

    考虑线段树维护区间的 \(s_i\) 表示在该区间内的答案。考虑如何合并。

    • 取左区间的 \(s\) 或者右区间的 \(s\)\(s\leftarrow \max(s_{l_i},s_{r_i})\)
    • 取左区间的 \(i,j\) 右区间的 \(k\) 或左区间的 \(i\) 右区间的 \(j,k\)。维护 \(m_i\) 表示区间最大 \(a\)\(n_i\) 表示区间最小 \(b\)\(g_i\) 表示区间最大 \(a_p-b_q(p<q)\)\(h_i\) 表示区间最大 \(a_p-b_q(p>q)\),则有 \(s\leftarrow \max(g_{l_i}+m_{r_i},m_{l_i}+h_{r_i})\)\(g_i=\max(g_{l_i},g_{r_i},m_{l_i}-n_{r_i})\)\(h_i=\max(h_{l_i},h_{r_i},m_{r_i}-n_{l_i})\)

    https://www.luogu.com.cn/record/64972767

    LG5278 算术天才⑨与等差数列

    形成差为 \(k\) 的等差数列相当于要满足以下条件:

    • \(\max-\min=k(r-l)\)
    • 区间的差分数组的 \(\gcd\)\(k\)
    • 区间内的数互不相同

    第一个条件可以用线段树维护区间最大/小值,第二个条件可以用线段树维护差分数组的 \(\gcd\),第三个条件先用一个 set 维护每个数前一个与自己相等的数 \(p\),然后 \(p\) 放到线段树上维护,条件相当于区间 \(p\)\(\max\)\(<l\)

    注意:\(set\) 一定要用自带的 lowerbound 否则会 t!

    还有求 \(n\) 个数的 \(\gcd\) 是均摊 \(O(n+\log v)\) 的,于是单点修区间 \(\gcd\)\(O(n(\log n+\log v))\) 的。

    https://www.luogu.com.cn/record/65080182

    POI2015 LOG-Logistyka

    一个美妙的结论。考虑转换“每次选出 \(c\) 个数 \(-1\) 并能选 \(s\) 次”这个条件。

    我们相当于把这些数填一个 \(s\times c\) 的矩阵并且每行不同。考虑把数分为 \(\ge s\)\(<s\) 的两种数。\(\ge s\)\(k\) 个数最多直接填满 \(k\) 列,剩下的数可以直接从上往下摊,即出现次数 \(<s\) 的数的总和要 \(\ge s\times (c-k)\)

    https://www.luogu.com.cn/record/65201956

    POI2011 ROZ-Difference

    考虑枚举最多的字符 \(a\) 和最少的字符 \(b\),归并起来得到一个长 \(a+b\)\(\pm 1\) 序列(\(a\)\(1\)\(b\)\(-1\)),我们求出包含 \(-1\) 的最大连续子序列即可。对于得到的一个极大值,如果其不含 \(-1\),在其两边找 \(-1\) 即可。

    https://loj.ac/s/1325069

    HNOI2015 开店

    点分树。目前还不是特别理解,但是主体思想是根据点分治建出重心分治树,然后对于一个问询就暴力跳来得到各个子树答案之和,至于如何计算和换根有一定相似之处。

    https://loj.ac/s/1327497

    LG4178 Tree (点分治模板)

    给定带权树,问距离 \(\le k\) 的点对数。

    套路化地,可以分为以下几个函数:

    • 找重心
      • 注意找 \(v\) 子树重心时,需要记录当前连通块 \(sz\) 要设为 \(sz_v\)
      • 找重心时 size 要重算
    • 统计信息
      • 定义点分树上的点 \(p\) 的点分数上子树 \(S_p\) ,其点分树上的父节点 \(fa_p\),则统计操作实则为统计 \(S_u\) 内部的信息。
      • 实际上统计由于是统计原树,所以实际上是在原树上搜索 \(S\) 所代表的连通块来得到答案。点分树上子树必然代表原树上的一个等价连通块,点分树上子树包含关系相当于原树上的连通块包含关系。所以,本质上就是将树在 \(O(\log n)\) 层内分治为 \(size\) 之和为 \(O(n\log n)\) 的连通块。
    • 遍历/建树
      • 建立点分树。具体操作为在建立 \(u\) 的点分树子树时先进行统计,然后再往下建树。

    这题合并分治的过程可以维护一个树状数组,然后求解即可。

    https://www.luogu.com.cn/record/65628431

    CQOI2015 选数

    \(l=\lfloor \frac{L}{k}\rfloor\)\(r=\lfloor\frac{H}{k}\rfloor\)\(p(x)=\lfloor\frac{r}{x}\rfloor-\lfloor\frac{l-1}{x}\rfloor\)(代表 \([l,r]\)\(x\) 倍数的个数)

    我们相当于要计算 \([l,r]\) 选数的最大公因数为 \(1\) 的方案数。我们发现对于 \(d>r-l\)\(d\) 的倍数最多在 \(r-l\) 中出现一次,而出现超过一次的 \(d\) 倍数的 \(d\) 的个数是 \(O(H-L)\) 的,所以我们考虑避掉 \(d>r-l\) 的统计。

    我们发现如果要是 \(d>r-l\) 的倍数,那么必须全部相等。所以我们设 \(f(x)\) 表示 \(\gcd\)\(x\) 且不全相等的方案数。\(f(x)=p(x)^n-p(x)-\sum_{x|y}f(y)\),倒着统计即可,复杂度 \(O((H-L)\log (H-L))\)

    https://loj.ac/s/1329439

    CQOI2015 网络吞吐量

    最短路+网络流(点限制->拆点)的清新小模板。

    注意! dijkstra 松弛的时候务必注意不能取等,不然会假。

    https://loj.ac/s/1329480

    LG3806 【模板】点分治

    先把询问离线下来,然后在处理 \(u\) 点的时候,把询问全部做了,复杂度 \(O(n\log^2n+nm\log n)\)

    https://www.luogu.com.cn/record/65712878

    IOI2011 Race

    对于分治子块时,我们还是可以维护一个桶,然后算。

    https://www.luogu.com.cn/record/66021072

  • 相关阅读:
    ubuntu安装 scala
    提交jar作业到spark上运行
    在IDEA上用python来连接集群上的hive
    spark在eclipse上配置
    【Spring AOP】Spring AOP的使用方式【Q】
    【Spring 源码】ApplicationContext源码
    【Spring 源码】Spring 加载资源并装配对象的过程(XmlBeanDefinitionReader)
    【Spring Cloud】Spring Cloud使用总结
    【坑】不要使用各种框架提供的内部List
    Lombok的使用
  • 原文地址:https://www.cnblogs.com/TetrisCandy/p/15755068.html
Copyright © 2011-2022 走看看