小技巧

并查集

如果有覆盖,更改等区间后区间不会再发生改变,此时可以用并查集将区间缩小。

例题:
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=1Cin2i1ni=(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 互质,那么 ka mod m k ⋅ a   m o d   m ,在 k[1,m] k ∈ [ 1 , m ] 时,模出来的数字可以不重复的取遍 [0,m1] [ 0 , m − 1 ] 的值。
证明:
a a 为任意一个整数, k1a=t1m+w k 1 a = t 1 ⋅ m + w k2a=t2m+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 ) 均为整数,且 k1k2,k1m,k2m k 1 ≠ k 2 , k 1 ≤ m , k 2 ≤ m ,那么显然 t1t2 t 1 ≠ t 2 ,也就是两个余数一样的数字,且都为 a a 的整倍数,那么相减得到 (k1k2)a=(t1t2)m ( k 1 − k 2 ) a = ( t 1 − t 2 ) m ,又因为 a,m a , m 互质,那么 (k1k2) ( k 1 − k 2 ) 定为 m m 的倍数,又因为 k1,k2 k 1 , k 2 小于 m m ,所以 k1k2 k 1 − k 2 不可能为 m m 的倍数,那么此时只有 k1=k2 k 1 = k 2 才成立,所以当两个 a a 的整倍数对 m m 取模时,余数肯定不同。

求下列式子值:

p,q p , q 为奇质数。

  • 式子一:

i=1p12i×qp+j=1q12j×pq ∑ i = 1 p − 1 2 ⌊ i × q p ⌋ + ∑ j = 1 q − 1 2 ⌊ j × p q ⌋

p=q p = q 时为 p×q14 p × q − 1 4 pq p ≠ q 时为 (p1)×(q1)4 ( p − 1 ) × ( q − 1 ) 4

  • 式子二:

i=1p1i×qp=p×(p1)2×(q1)p ∑ i = 1 p − 1 ⌊ i × q p ⌋ = p × ( p − 1 ) 2 × ( q − 1 ) p

因为当 i[0,p1] i ∈ [ 0 , p − 1 ] 时, (i×q mod p) ( i × q   m o d   p ) 会取遍 [0,p1] [ 0 , p − 1 ] 的值,而这些值是在取整时会被去掉,所以用所有和减去 p1i=0i ∑ i = 0 p − 1 i 就是答案,等差数列求和公式一用就好啦。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

VictoryCzt

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值