• HDU 6058


    /*
    HDU 6058 - Kanade's sum [ 思维,链表 ]  |  2017 Multi-University Training Contest 3
    题意:
    	给出排列 a[N],求所有区间的第k大数之和
    	N <= 5e5, k <= 80
    分析:
    	先求出每个数的位置pos[]数组
    	然后维护一个单调链表,按数字从大到小向里面加该数字的位置
    		即对于i的位置 pos[i] 找到链表中比它大的第一个位置和比它小的第一个位置,将pos[i]加到两个之间
    	这部分用set实现,复杂度 O(nlogn)
    	
    	则对于数字i,链表中所有的位置均为比i大的数的位置
    	然后滑动窗口更新答案
    		即维护 l,r,要求 l 到 r 之间包含 pos[i] 且恰好 k 个数,这个时候 i 就是第k小
    	复杂度 O(nk)
    	
    	总复杂度 O(nlogn + nk)
    */
    #include <bits/stdc++.h>
    using namespace std;
    const int N = 5e5+5;
    int t, n, k;
    int a[N], pos[N];
    int pre[N], nxt[N];
    set<int> st;
    set<int>::iterator it;
    long long ans;
    void solve(int x)
    {
        int l, r, lx, rx, cnt = k-1;
        l = r = x;
        while (cnt && pre[l] != 0) l = pre[l], cnt--;
        while (cnt && nxt[r] != n+1) r = nxt[r], cnt--;
        while (l != nxt[x])
        {
            lx = l-pre[l];
            rx = nxt[r]-r;
            ans += (long long)lx * rx * a[x];
            if (nxt[r] == n+1) break;
            l = nxt[l];
            r = nxt[r];
        }
    }
    int main()
    {
        scanf("%d", &t);
        while (t--)
        {
            st.clear();
            scanf("%d%d", &n, &k);
            for (int i = 1; i <= n; i++)
            {
                scanf("%d", a+i);
                pos[a[i]] = i;
            }
            pre[n+1] = 0;
            nxt[0] = n+1;
            st.insert(0);
            st.insert(n+1);
            ans = 0;
            for (int i = n; i >= 1; i--)
            {
                it = st.lower_bound(pos[i]);
                nxt[pos[i]] = *it;
                pre[*it] = pos[i];
                --it;
                pre[pos[i]] = *it;
                nxt[*it] = pos[i];
                if (n-i+1 >= k) solve(pos[i]);
                st.insert(pos[i]);
            }
            printf("%lld
    ", ans);
        }
    }
    

      

    我自倾杯,君且随意
  • 相关阅读:
    最实用的logback讲解(2)—appender
    深入理解lombok
    idea(三)最值得安装的几款插件
    idea(二)初次安装强烈建议修改的配置
    swagger2的使用和swagger2markup离线文档的生成(最简单的方式)
    maven(一) 基础知识
    maven(二)pom文件详解
    ubuntu下jdk的安装
    maven(三)最详细的profile的使用
    profile之springboot
  • 原文地址:https://www.cnblogs.com/nicetomeetu/p/7271813.html
Copyright © 2020-2023  润新知