牛客OI周赛6-提高组 A 大法师与魔法石

大法师与魔法石

思路:

对于一个ai, 它可以构成区间[ai/v, ai]

假设和它相邻的为aj, 那么ai 和 aj 构成的区间为[(ai+aj) / v, ai+aj]

那么这两个区间能合并的条件是 (ai + aj) / v <= ai

即aj <= (v - 1)ai (v >= 2)

又因为(v - 1) ai >= ai

所以aj <= ai

所以把每个ai和它相邻的比它小的数连接起来考虑

用单调栈求出每个位置之前和之后第一个比它大的数就可以了

代码:

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pli pair<LL, int>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head

const int N = 1e5 + 5;
int a[N], pre[N], nxt[N];
pair<LL, LL> q[N];
LL sum[N];
stack<int> st;
int main() {
    int T, n, v;
    scanf("%d", &T);
    while(T--) {
        scanf("%d %d", &n, &v);
        for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
        a[0] = INT_MAX;
        a[n+1] = INT_MAX;
        while(!st.empty()) st.pop();
        st.push(0);
        for (int i = 1; i <= n; i++) {
            while(a[st.top()] <= a[i]) st.pop();
            pre[i] = st.top();
            st.push(i);
        }
        while(!st.empty()) st.pop();
        st.push(n+1);
        for (int i = n; i >= 1; i--) {
            while(a[st.top()] <= a[i]) st.pop();
            nxt[i] = st.top();
            st.push(i);
        }
        for (int i = 1; i <= n; i++) sum[i] = sum[i-1] + a[i];
        for (int i = 1; i <= n; i++) {
            q[i].fi = (a[i] + v - 1) / v;
            q[i].se = sum[nxt[i]-1] - sum[pre[i]];
        }
        sort(q+1, q+1+n);
        LL ans = 0;
        q[0].se = -1;
        for (int i = 1; i <= n; i++) {
            ans += q[i].se - q[i].fi + 1;
            if(q[i].fi <= q[i-1].se) ans -= q[i-1].se - q[i].fi + 1;
        }
        printf("%lld\n", ans);
    }
    return 0;
}

 

posted @ 2018-11-20 15:37  Wisdom+.+  阅读(162)  评论(0编辑  收藏  举报