EOJ Monthly 2019.3 (based on March Selection) C. 线段树 --剪枝

https://acm.ecnu.edu.cn/contest/151/problem/C/

EOJ Monthly 2019.3 (based on March Selection) C. 线段树 --剪枝_第1张图片
EOJ Monthly 2019.3 (based on March Selection) C. 线段树 --剪枝_第2张图片
解析
https://acm.ecnu.edu.cn/blog/entry/342/
EOJ Monthly 2019.3 (based on March Selection) C. 线段树 --剪枝_第3张图片

递归 (超时)

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef long long LL;
long long make(long long l,long long r){
    long long d = r - l + 1;
    if(l==r){
        return l;
    }else if(l<1){
        return -1;
    }else if(l > 1000*(r-l+1)){
        return -1;
    }else if(r>2000000000){
        return -1;
    }else if(l==1){
        return r;

    }else if(l>1 && r<=2000000000){
        vector<int>ret;
        long long k4 = make(l,r+d-1);
        //cout<<"k4 "<
        if(k4>0){
            ret.push_back(k4);
            //return k4;
        }

        long long k1 = make(l-d-1,r);
        //cout<<"k1 "<
        if(k1>0){
            ret.push_back(k1);
            //return k1;
        }

        long long k2 = make(l-d,r);
        //cout<<"k2 "<
        if(k2>0){
            ret.push_back(k2);
            //return k2;
        }
        long long k3 = make(l,r+d);
        //cout<<"k3 "<
        if(k3>0){
            ret.push_back(k3);
            //return k3;
        }
        if(ret.size()==0)
            return -1;
        else{
            LL min1 = LONG_MAX;
            for(auto i: ret){
                if(i<min1){
                    min1 = i;
                }
            }
            return min1;
        }
    }
}


int main()
{
    int T;
    cin>>T;
    long long l,r;
    long long rm = 2100000000;

    while(T--){
        cin>>l;
        cin>>r;
        //递归超时
        cout<<make(l,r)<<endl;
    }
    return 0;
}


枚举n 通过

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef long long LL;

long long make1(long long l,long long r){
    LL len = r - l + 1;

    for(LL i=0;i<=31;i++){
        LL pw = (LL)pow(2,i);
        LL left =pw*(len-1);
        LL right = pw*(len+1);
        for(LL n=left;n<=right;n++){
            if(l==1){
                return r;
            }
            LL mid = (1+n)/2;
            LL le = mid + 1;
            LL ri = n;
            //mid = (le+ri)/2;
            while( ri-le > r-l){
                mid = (le+ri)/2;
                if(le > 1000*(ri-le+1)){
                    return -1;
                }
                else if(mid<l){
                    le = mid+1;
                }else if(mid>=r){
                    ri = mid;
                }else{
                    break;
                }

            }
            if(le==l && ri==r){
                return n;
            }

        }

    }
    return -1;
}

int main()
{
    int T;
    cin>>T;
    long long l,r;
    long long rm = 2100000000;
    while(T--){
        cin>>l;
        cin>>r;
        cout<<make1(l,r)<<endl;
    }
    return 0;
}

你可能感兴趣的:(#,other,算法总结)