HDU 6058 Kanade's sum (区间第k大的数的贡献)
2017-08-02 16:06
471 查看
思路:
维护一个链表,初始状态为输入的序列。然后从1开始到n,对每个数统计他在哪些区间中,然后乘以这个数,作为这个数做出的贡献。
统计他在某些区间的办法:
对于每个数i,我们向左找k-1个比他大的数(由于我们是从小到大处理的,且每个数处理后就在链表里删除了,所以这里我们直接一个个跳就好)。假设这第k-1个数为b,再向左找第k个为a,那么我们可以得知,(a,b】中的数皆可作为满足条件的区间的左端点。然后相似的考虑右端点,在这种情况下i的右边第一个比i大的数左边的数都可以作为满足条件的区间的右端点。
然后我们将区间整体向右走一跳。变成左边有k-2个比i大的,右边有1的比i大的,然后同理统计。
区间递推知道左端点为i。
至此我们将i对所有它出现的区间都统计了贡献。
然后我们就可以在链表里删除这个数。
然后接着处理下一个。
#include <iostream> #include <cmath> #include <cstdio> #include <cstring> #include <algorithm> typedef long long int lli; using namespace std; struct pp{ int tol,tor; }head[600000]; int lis[600000]; lli a[600000]; // 自适应辛普森 int main(){ // freopen("1003.in","r",stdin); // freopen("my.txt","w",stdout); int cas,n,k,v; scanf("%d",&cas); while(cas--){ scanf("%d%d",&n,&k); for(int i = 1;i <= n;i++){ scanf("%d",&v); lis[i] = v; a[v] = i; head[i].tol = i-1; head[i].tor = i+1; } head[0].tor = 1;head[n+1].tor = 0; lis[0] = 0;a[0] = 0; lis[n+1] = n+1;a[n+1] = n+1; lli ans = 0; for(int i = 1;i <= n;i++){ int n1 = a[i],n2,n3 = a[i],j; for(j = 1;j <= k-1 && n1;j++){ n1 = head[n1].tol; } if(!n1){ j--; n1 = head[n1].tor; for(;j <= k-1 && n3!=n+1;j++){ n3 = head[n3].tor; } if(j != k) break; } for(int cnt = 1;cnt <= k && n1 <= a[i] &&n3;cnt++){ if(n3 != n+1) ans += (lli)i*(lli)(a[lis[n1]]-a[lis[head[n1].tol]])*(lli)(a[lis[head[n3].tor]]-a[lis[n3]]); n1 = head[n1].tor; n3 = head[n3].tor; } n1 = head[a[i]].tol,n2 = head[a[i]].tor; head[n1].tor = n2; head[n2].tol = n1; } printf("%lld\n",ans); } return 0; }
相关文章推荐
- hdu 6058 Kanade's sum(区间跳跃)
- 2017 多校训练第三场 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【思维+链表模拟】
- HDU 6058 Kanade's sum
- 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(模拟)
- 【多校训练】hdu 6058 Kanade's sum
- HDU-6058 Kanade's sum(计数)
- HDU 6058 Kanade's sum 逆序求第k大
- hdu 6058 Kanade's sum(链表)(2017 Multi-University Training Contest - Team 3 )
- hdu 6058 Kanade's sum(思维)
- 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 链表+枚举