• 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

  • 相关阅读:
    js图片加载效果(延迟加载+瀑布流加载)
    iOS仿支付宝芝麻信用仪表盘效果
    Spark GraphX 的数据可视化
    [Animations] 快速上手 iOS10 属性动画
    iOS蓝牙BLE4.0通信功能
    微信小程序项目实战之天气预报
    Android利用温度传感器实现带动画效果的电子温度计
    Eclipse集成ijkplayer并实现本地和网络视频播放等
    Android HandlerThread详解
    AsyncTask 异步任务基本使用-下载视频
  • 原文地址:https://www.cnblogs.com/bryce1010/p/9386841.html
Copyright © 2020-2023  润新知