zoukankan      html  css  js  c++  java
  • 《算法竞赛进阶指南》0x06倍增 Acwing GeniusACM

    题目链接:https://www.acwing.com/problem/content/description/111/

    首先定义了集合S的校验值,取出m对数,使得每对平方之后求和最大,这个值成为集合S的校验值。现在给定一个数列,求满足每段的校验值小于T的前提下最小能把数列分成连续的几段?

    利用倍增的思想对右端点进行倍增,并且结合归并排序去除冗余的排序。具体解释在代码中阐明。二进制就是这么神奇而高效。

    代码如下:

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define maxn 500010
    typedef long long ll;
    int n,m,ed;
    ll k;//注意k是1e18范围的 
    ll a[maxn],b[maxn],c[maxn];//a:无序,原数组,b:分两段有序,c:归并之后的合并数组
    void gb(int l,int mid,int r){//[l,mid]与[mid+1,r] 归并,
        int i=l,j=mid+1;//双指针扫描
        for(int k=l;k<=r;k++){
            if(j>r || (i<=mid && b[i] <= b[j]))c[k]=b[i++];
            else c[k]=b[j++];
        } 
    } 
    ll calc(int l,int r){//计算校验值 
        if(r>n)r=n;
        int t=min((r-l+1)/2,m);//将[l,r]区间分成的最大的对数
        ll ans=0;
        for(int i=ed+1;i<=r;i++) b[i]=a[i];//将a[i]中上次mid+1的位置到r的序列放入b中并排序
         sort(b+ed+1,b+r+1);//[ed+1,r]部分排序
         gb(l,ed,r);
         for(int i=0;i<t;i++){
             ans+=(c[r-i]-c[l+i])*(c[r-i]-c[l+i]);
         } 
         return ans;
    }
    void Genius_ACM(){
        int ans=0;//分的段数
        int l=1,r=1;
        b[1]=a[1];
        ed=1;//ed表示的是上次倍增的结束位置
        while(l<=n){
            int p=1;//每一段都是从2^0开始倍增的
            while(p){
                ll num=calc(l,r+p);
                if(num<=k){
                    ed=r=min(r+p,n);
                    for(int i=l;i<=r;i++)b[i]=c[i];//将归并的有序序列放入b中 
                     if(r==n)break;
                     p<<=1;
                }else p>>=1;//倍增失败,缩小倍增跨度
            } 
            ans++;
            l=r+1;
        } 
        cout<<ans<<endl;
    }
    int main(){
        int t;
        cin>>t;
        while(t--){
            cin>>n>>m>>k;
            for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
            Genius_ACM();
        }
        return 0;
    }
  • 相关阅读:
    git 的安装与初始化
    django的ORM
    elasticsearch基本使用
    给django视图类添加装饰器
    python的编码
    为django项目配置celery的后台启动
    django+celery +rabbitmq
    hadoop安装
    django中间件
    Blockchain For Dummies(IBM Limited Edition
  • 原文地址:https://www.cnblogs.com/randy-lo/p/13137638.html
Copyright © 2011-2022 走看看