hdu 6058 Kanade's sum
2017-08-09 19:25
459 查看
题意:给你一个一个数列。问1到n所有子区间中第k大值得和是多少。
分析:可以美枚举每一个数,计算它可以做多少次第k大值。因为k很小,所以可以枚举一个数,找到它前面第k个比它大的数和后面第k个比它大的数,然后计算。找的时候可以用单调栈维护。
分析:可以美枚举每一个数,计算它可以做多少次第k大值。因为k很小,所以可以枚举一个数,找到它前面第k个比它大的数和后面第k个比它大的数,然后计算。找的时候可以用单调栈维护。
#include<cstdio> #include<stack> #include<cstring> using namespace std; typedef long long ll; const int maxn = 5e5 + 5; ll a[maxn]; ll l[maxn], r[maxn]; stack<ll> s; ll le[100], re[100]; int main(){ int T; ll n, k; scanf("%d", &T); while(T--){ memset(l, 0, sizeof(l)); memset(r, 0, sizeof(r)); ll ans = 0; scanf("%lld%lld", &n, &k); while(!s.empty()) s.pop(); for(int i = 1; i <= n; i++){ scanf("%lld", &a[i]); while(!s.empty() && a[i] > a[s.top()]){ s.pop(); } if(s.empty()) l[i] = 0; else l[i] = s.top(); s.push(i); } while(!s.empty()) s.pop(); for(int i = n; i >= 1; i--){ while(!s.empty() && a[i] > a[s.top()]){ s.pop(); } if(s.empty()) r[i] = n + 1; else r[i] = s.top(); s.push(i); } for(int i = 1; i <= n; i++){ memset(le, 0, sizeof(le)); memset(re, 0, sizeof(re)); int tot1 = 0, tot2 = 0; int j = i - 1; le[0]=i; for(tot1 = 1; tot1 <= k; tot1++){ if(j == 0) { break; }else{ while(j > 1 && a[j] < a[i]){ j = l[j]; } if(a[j] > a[i]) le[tot1] = j--; else break; } } j = i + 1; re[0] = i; for(tot2 = 1; tot2 <= k; tot2++){ if(j > n) { break; }else{ while(j < n && a[j] < a[i]){ j = r[j]; } if(a[j] > a[i]) re[tot2] = j++; else break; } } tot1--, tot2--; if(tot1 < k){ ll tl = le[tot1]; if(k - tot1 - 1 > tot2) continue; if(k - tot1 - 1 == tot2){ ans += a[i] * (n - re[tot2] + 1) * tl; }else ans += a[i] * (re[k - tot1] - re[k - tot1 - 1]) * tl; } for(int j = tot1 - 1; j >= 0; j--){ ll pos = k - j - 1; ll tl = le[j] - le[j + 1]; /* if(j == 0) tl = 1; //if(pos > tot2) break; if(pos == 0){ ans += a[i] * tl; }else*/ if(pos < tot2){ ans += a[i] * (tl * (re[pos + 1] - re[pos])); }else if(pos == tot2){ ans += a[i] * (tl * (n - re[pos] + 1)); break; } } } printf("%lld\n", ans); } }
相关文章推荐
- HDU 6058 Kanade's sum 逆序求第k大
- 2017 Multi-University Training Contest - Team 3 1003(hdu 6058) Kanade's sum(链表)(set)
- hdu 6058 Kanade's sum(链表)(2017 Multi-University Training Contest - Team 3 )
- hdu 6058 Kanade's sum
- HDU 6058 Kanade's sum(链表)
- HDU 6058 Kanade's sum
- HDU 6058 Kanade's sum(链表)
- hdu 6058 Kanade's sum(链表)(2017 Multi-University Training Contest - Team 3 )
- HDU 6058 Kanade's sum (区间第k大的数的贡献)
- (2017多校训练第三场)HDU - 6058 Kanade's sum 链表
- HDU 6058 Kanade's sum 思维+ 模拟链表
- HDU 6058 Kanade's sum
- hdu 6058 Kanade's sum(链表)(2017 Multi-University Training Contest - Team 3 )
- hdu 6058 Kanade's sum(区间跳跃)
- hdu 6058 Kanade's sum(链表)(2017 Multi-University Training Contest - Team 3 )
- hdu 6058 Kanade's sum
- 2017多校第3场 HDU 6058 Kanade's sum 双链表,思维
- hdu 6058 Kanade's sum(链表)(2017 Multi-University Training Contest - Team 3 )
- HDU-6058 Kanade's sum(计数)
- hdu 6058 Kanade's sum(链表)(2017 Multi-University Training Contest - Team 3 )