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;
    }
  • 相关阅读:
    快速查看表结构(zml)
    康尼机电的发送邮件的功能2
    康尼机电的发送邮件的功能1
    8.2文件控制总览只循环了第一行
    ClientScript.RegisterStartupScript
    康尼机电的委托协议中的点击操作显示标签卡的功能
    1020 Tree Traversals (25 分)
    1017 Queueing at Bank (我自己写的模拟时间的版本)
    1016 Phone Bills ( vector的使用)
    1015 Reversible Primes
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4975624.html
Copyright © 2011-2022 走看看