zoukankan      html  css  js  c++  java
  • 小技巧

    并查集

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

    例题:
    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。

    i=1nCni2i1ni=(1+2)n=3n

    牛顿二项式定理

    枚举二进制子集的方法

    for(int s=i;;s=(s-1)&i){
        work(s);
        if(!s) break;
    }

    如果a,m互质,那么ka mod m,在k[1,m]时,模出来的数字可以不重复的取遍[0,m1]的值。
    证明:
    a为任意一个整数,k1a=t1m+wk2a=t2m+w(k1,k2,t1,t2,a,m,w)均为整数,且k1k2,k1m,k2m,那么显然t1t2,也就是两个余数一样的数字,且都为a的整倍数,那么相减得到(k1k2)a=(t1t2)m,又因为a,m互质,那么(k1k2)定为m的倍数,又因为k1,k2小于m,所以k1k2不可能为m的倍数,那么此时只有k1=k2才成立,所以当两个a的整倍数对m取模时,余数肯定不同。

    求下列式子值:

    p,q为奇质数。

    • 式子一:

    i=1p12i×qp+j=1q12j×pq

    p=q时为p×q14pq时为(p1)×(q1)4

    • 式子二:

    i=1p1i×qp=p×(p1)2×(q1)p

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

  • 相关阅读:
    C++对象模型2--指针cout结果
    C++对象模型4--有重写的单继承
    C++对象模型3--无重写的单继承
    C++对象模型6--对象模型对数据访问的影响
    C++对象模型--C++对象模型
    二叉树先序遍历算法实现
    C/C++指针和数组的关系
    xml 基础学习备忘
    Maven 更换远程仓库地址
    Maven 添加自定义 archetype
  • 原文地址:https://www.cnblogs.com/VictoryCzt/p/10053437.html
Copyright © 2011-2022 走看看