zoukankan      html  css  js  c++  java
  • bryce1010专题训练——CDQ分治

    Bryce1010模板

    CDQ分治

    1、与普通分治的区别

    普通分治中,每一个子问题只解决它本身(可以说是封闭的)
    分治中,对于划分出来的两个子问题,前一个子问题用来解决后一个子问题而不是它本身

    2、试用的情况

    在很多问题中(比如大多数数据结构中),经常需要添加一些动态问题,然而对动态问题的处理总是不如静态问题来得方便,于是就有了分治
    但使用分治的前提是必须有一下两个性质:

    • 修改操作对区间询问的贡献独立,修改操作互相不影响
    • 题目允许使用离线算法

    2.1 一般步骤

    • 将整个操作序列分为两个长度相等的部分(分)
    • 递归处理前一部分的子问题(治1)
    • 计算前一部分的子问题中的修改操作对后一部分子问题的影响(治2)
    • 递归处理后一部分的子问题

    特别说明:
    在整个过程中,最核心的就是步骤3
    此时前一部分子问题中的修改操作相对后一部分子问题来说是静态处理,因此可以更加方便地计算后一部分子问题

    3.题集

    3.1 51nod 1376 最长递增子序列的数量

    用f[i]表示以第i个数结尾的LIS的长度和该长度的数量 len count
    显然

    f[i].first=max{f[i].first}+1,j<i&&a[j]<a[i]

    f[i].second=jf[i].second,f[j].first=f[i].first1

    二维偏序,一维下标,二维值;
    直接cdq分治处理:

    #include<bits/stdc++.h>
    using namespace std;
    
    
    const int MAXN=1e5+10;
    const int INF=0x3f3f3f3f;
    const int MOD=1e9+7;
    int n,a[MAXN];
    #define P pair<int,int>
    P f[MAXN];//LIS length,count
    void getMax(P& x,P y)
    {
        if(x.first<y.first)x=y;
        else if(x.first==y.first)
        {
            if((x.second+=y.second)>=MOD)
                x.second-=MOD;
        }
    }
    
    int id[MAXN];
    
    /*排序小技巧
    避开相等,间隔排序,把可能成为询问的排到第一个
    */
    bool cmp(int x,int y)
    {
        if(a[x]!=a[y])return a[x]<a[y];
        return x>y;
    }
    
    
    void cdq(int l,int r)
    {
        if(l==r)return;
        int m=(l+r)>>1;
        cdq(l,m);
    
        for(int i=l;i<=r;i++)id[i]=i;
        sort(id+l,id+r+1,cmp);
    
        P maxf(0,0);
        for(int i=l;i<=r;i++)
        {
            int idx=id[i];
            if(idx<=m)getMax(maxf,f[idx]);
            else
            {
                P cur=maxf;
                ++cur.first;
                getMax(f[idx],cur);
            }
        }
        cdq(m+1,r);
    }
    
    
    
    
    
    
    int main()
    {
    
        ios_base::sync_with_stdio(0);
    
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d",a+i);
        for(int i=1;i<=n;i++)f[i]=P(1,1);
        cdq(1,n);
        P ans(0,0);
        for(int i=1;i<=n;i++)getMax(ans,f[i]);
        printf("%d
    ",ans.second);
        return 0;
    }
    
    

    3.2 BZOJ 3262 陌上花开

    3.3 HDU4742 Pinball Game 3D

    参考:
    https://blog.csdn.net/tham_/article/details/68555100

  • 相关阅读:
    WPF中用户控件对比自定义控件(UserControl VS CustomControl) upcode
    WinCE7开发过程 upcode
    App/Shell启动过程 upcode
    WinCE启动过程 upcode
    ASP.NET 4.0验证请求 A potentially dangerous Request.Form value was detected from the client
    HTML5 开发工具推荐
    用.NET部署卸载window服务
    C#去除HTML标签方法
    正在中止线程 的问题解决
    【转载】纯CSS画的基本图形(矩形、圆形、三角形、多边形、爱心、八卦等)
  • 原文地址:https://www.cnblogs.com/bryce1010/p/9386841.html
Copyright © 2011-2022 走看看