zoukankan      html  css  js  c++  java
  • POJ

    题意:询问一个静态序列的连续区间和绝对值最接近t的下标。

    分析:由于询问的是绝对值,可以用前缀和相减得到区间和,并且和位置前后没有关系。于是把记录下标信息以后把

    前缀和排序枚举大的前缀pj,pj-pi ≈ t,满足条件的:有pj-t的plower_bound以及plower_bound-1

    而pj-t也是单调的,再用一个下标i去维护就好。

    /*********************************************************
    *            ------------------                          *
    *   author AbyssalFish                                   *
    **********************************************************/
    #include<cstdio>
    #include<iostream>
    #include<string>
    #include<cstring>
    #include<queue>
    #include<vector>
    #include<stack>
    #include<vector>
    #include<map>
    #include<set>
    #include<algorithm>
    #include<cmath>
    #include<numeric>
    using namespace std;
    
    const int maxn = 1e5+1;
    
    int t, n, k;
    
    typedef pair<int,int> node;
    #define val first
    #define idx second
    node a[maxn];
    
    int best, lb, ub;
    
    void update(int i,int j)
    {
        if(abs(a[j].val - a[i].val - t) < abs(best-t)){
            best = a[j].val - a[i].val;
            lb = a[i].idx; ub = a[j].idx;
        }
    }
    
    void solve()
    {
    
        a[0].val = a[0].idx = 0; //空前缀是必要的
        for(int i = 1; i <= n; i++) {
            a[i].val += a[i-1].val;
            a[i].idx = i;
        }
        sort(a,a+n+1);
        while(k--){
            scanf("%d",&t);
            best = a[1].val-a[0].val, lb = a[1].idx, ub = a[0].idx; //(lb,ub]
            for(int i = 0, j = 1; j <= n; j++){
                while(i < j && a[j].val - a[i].val > t) { //[i,j]
                    i++;
                }
                if(i) update(i-1,j);
                if(i < j) update(i,j);
            }
            if(ub < lb) swap(ub, lb);
            printf("%d %d %d
    ", best, lb+1, ub);
        }
    
    }
    
    //#define LOCAL
    int main()
    {
    #ifdef LOCAL
        freopen("in.txt","r",stdin);
    #endif
    
        while(scanf("%d%d",&n,&k),n){
            for(int i = 1; i <= n; i++){
                scanf("%d",&a[i].val);
            }
            solve();
        }
        return 0;
    }
  • 相关阅读:
    matlab如何写一个类
    最大稳定极值区域(MSER)检测
    Excel中公式的绝对引用和相对引用单元格
    c++中自增(++)和自减(--)操作符
    C++中的c_str()函数用法
    一些常用的图像数据库
    浅谈C++中指针和引用的区别
    selenium之find_element_by_xpath定位元素
    python selenium使用
    H5页面调用手机扫一扫功能
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4975624.html
Copyright © 2011-2022 走看看