并查集
如果有覆盖,更改等区间后区间不会再发生改变,此时可以用并查集将区间缩小。
例题:
1. [HAOI2014]贴海报
2. [COCI2010-2011#5] SLIKA
3. P4145 上帝造题的七分钟2 / 花神游历各国
有些开根或者乘方取模(欧拉)等,到了一定规模时数字不再变化,可以缩小范围。
树链剖分的一些做题时的小技巧
- 边权处理
方法:下放边权到深度较深的点上,因为每个点入度为1,所以能保证每个点对于唯一一条边。
例题:[USACO11DEC]牧草种植Grass Planting
核心地方:就是在最后的时候更新处的左端点加一即可。
void up(int a,int b){
while(top[a]!=top[b]){
if(dep[top[a]]<dep[top[b]]) swap(a,b);
update(1,1,tim,num[top[a]],num[a]);
a=f[top[a]];
}
if(dep[a]>dep[b]) swap(a,b);
update(1,1,tim,num[a]+1,num[b]);
}
- 区间,单点等
如果是一些简单的修改查询,用树状数组可以大大减少常数复杂度。
- 轻重链之间的处理
如果线段树合并时会有跨区间的特殊处理,那么在跳轻重链之间时,也要处理。
例题:[SDOI2011]染色
int query(int o,int l,int r,int L,int R){
if(L<=l&&r<=R)return sum[o];
int mid=l+r>>1;
pushdown(o);
int ans=0;
if(L>mid) ans=query(o<<1|1,mid+1,r,L,R);
else if(R<=mid) ans=query(o<<1,l,mid,L,R);
else{
ans=query(o<<1,l,mid,L,mid);
ans+=query(o<<1|1,mid+1,r,mid+1,R);
ans-=(rc[o<<1]==lc[o<<1|1]);
}
pushup(o);
return ans;
}
int findcol(int o,int l,int r,int pos){
if(l==r) return lc[o];
pushdown(o);
int mid=l+r>>1,ans=0;
if(pos<=mid) ans=findcol(o<<1,l,mid,pos);
else ans=findcol(o<<1|1,mid+1,r,pos);
pushup(o);
return ans;
}
int getans(int a,int b){
int ans=0;
while(top[a]!=top[b]){
if(dep[top[a]]<dep[top[b]]) swap(a,b);
ans+=query(1,1,tim,num[top[a]],num[a]);
ans-=(findcol(1,1,tim,num[top[a]])==findcol(1,1,tim,num[f[top[a]]]));
//轻重链交换时,如果交界处一样要减1
a=f[top[a]];
}
if(dep[a]>dep[b]) swap(a,b);
ans+=query(1,1,tim,num[a],num[b]);
return ans;
}
如果强制在线的删边并查集,如果是规则图(矩阵完全图),删边操作可以转换为对偶图的连边操作,判断不连通就是对偶图上有环。
(二维)树状数组的区间修改询问操作可以用差分数组来维护。
- 上帝造题的七分钟1
[SDOI2015]序列统计
我们用原根把相乘变作指数的相加,然后就可以用NTT。
∑ni=1Cin2i1n−i=(1+2)n=3n ∑ i = 1 n C n i 2 i 1 n − i = ( 1 + 2 ) n = 3 n
牛顿二项式定理
枚举二进制子集的方法
for(int s=i;;s=(s-1)&i){
work(s);
if(!s) break;
}
如果
a,m
a
,
m
互质,那么
k⋅a mod m
k
⋅
a
m
o
d
m
,在
k∈[1,m]
k
∈
[
1
,
m
]
时,模出来的数字可以不重复的取遍
[0,m−1]
[
0
,
m
−
1
]
的值。
证明:
令
a
a
为任意一个整数,
k1a=t1⋅m+w
k
1
a
=
t
1
⋅
m
+
w
,
k2a=t2⋅m+w
k
2
a
=
t
2
⋅
m
+
w
,
(k1,k2,t1,t2,a,m,w)
(
k
1
,
k
2
,
t
1
,
t
2
,
a
,
m
,
w
)
均为整数,且
k1≠k2,k1≤m,k2≤m
k
1
≠
k
2
,
k
1
≤
m
,
k
2
≤
m
,那么显然
t1≠t2
t
1
≠
t
2
,也就是两个余数一样的数字,且都为
a
a
的整倍数,那么相减得到
(k1−k2)a=(t1−t2)m
(
k
1
−
k
2
)
a
=
(
t
1
−
t
2
)
m
,又因为
a,m
a
,
m
互质,那么
(k1−k2)
(
k
1
−
k
2
)
定为
m
m
的倍数,又因为
k1,k2
k
1
,
k
2
小于
m
m
,所以
k1−k2
k
1
−
k
2
不可能为
m
m
的倍数,那么此时只有
k1=k2
k
1
=
k
2
才成立,所以当两个
a
a
的整倍数对
m
m
取模时,余数肯定不同。
求下列式子值:
p,q p , q 为奇质数。
- 式子一:
当 p=q p = q 时为 p×q−14 p × q − 1 4 , p≠q p ≠ q 时为 (p−1)×(q−1)4 ( p − 1 ) × ( q − 1 ) 4
- 式子二:
因为当 i∈[0,p−1] i ∈ [ 0 , p − 1 ] 时, (i×q mod p) ( i × q m o d p ) 会取遍 [0,p−1] [ 0 , p − 1 ] 的值,而这些值是在取整时会被去掉,所以用所有和减去 ∑p−1i=0i ∑ i = 0 p − 1 i 就是答案,等差数列求和公式一用就好啦。
1677

被折叠的 条评论
为什么被折叠?



