对double类型数组初始化:
无穷大0x42;无穷小0xc2。
模板类的read函数:
防止读longlong类型的数字时爆int
template<class Type>
inline Type read(void){
Type 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=getchar();}
return f*x;
}
读int类时int a=read<int>();
,读longlong类时LL a=read<LL>();
。贼好用。
线段树防写炸
在pushdown的时候,把更新子节点的值写进一个函数,在Update的时候也能用,防止手抽写炸。
inline void Add(int o,int v){
add[o]+=v;
sum[o]+=len[o]*v;
minv[o]+=v;
maxv[o]+=v;
return;
}
inline void pushdown(int o){
if(!add[o])return;
Add(lson,add[o]);
Add(rson,add[o]);
add[o]=0;
}
inline void Update(int o,int l,int r,int ql,int qr,int v){
if(ql<=l&&r<=qr){Add(o,v);return;}
//Do something
}
滚动数组
可以开两个数组f和g,f表示当前i阶段的DP数组,g表示i-1阶段的DP数组。
for(register int i=1;i<=n;++i,swap(f,g))//转移
{
//do something
}
树上求链交
求链(a,b)与(c,d)的交。
设(c_1=lca(a,b), c_2=lca(c,d)),且排序后(dep[c_1]leq dep[c_2])。
设(d_1 = lca(a,c), d_2 = lca(a,d), d_3 = lca(b,c), d_4 = lca(b,d)),且排序后(dep[d_1]leq dep[d_2] leq dep[d_3]leq dep[d_4]).
两条链有交当且仅当(dep[c_1]leq dep[d_1]) 且(dep[c_2] leq dep[d_3]),此时(d_3)与(d_4)是两条链的交。
Splay函数
注意在Splay函数的最后写一行update(x)
,否则有可能会有未知错误。
inline void splay(int x, int goal) {
for (int f; (f = fa[x]) != goal; rotate(x))
if (fa[f] != goal) rotate(get(x) == get(f) ? f : x);
if (!goal) root = x;
update(x);
}