码迷,mamicode.com
首页 > 其他好文 > 详细

【链表】2017多校训练3 HDU 6058 Kanade's sum

时间:2017-08-02 14:59:49      阅读:140      评论:0      收藏:0      [点我收藏+]

标签:ring   维护   can   play   区间   bsp   acm   using   时间   

acm.hdu.edu.cn/showproblem.php?pid=6058

【题意】

  • 给定一个排列,计算技术分享
  • 技术分享
  • 技术分享
  • 技术分享技术分享

【思路】

  • 计算排列A中每个数的贡献,即对于每个ai,计算有ni个区间满足ai是区间中的第k大,那么ai对答案的贡献就是ai*ni
  • 以ai为起点,统计ai右边离ai最近的,比ai大的k个数的位置
  • 同理统计左边的位置,组合得到答案
  • 关键是得到比ai大的离ai最近的k个数的位置
  • 因为是排列,所以每个数都不相等,可以记录每个数的位置,然后从小到大枚举ai,这样维护一个双向链表,保证链表中的数就是满足条件的离ai最近的比ai的数
  • 每次处理ai之后把ai从链表中删除,这样处理ai+1时链表中就都是比ai大的数
  • 删除操作是O(1),总的时间复杂度是O(nk)

【Acceped】

技术分享
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<string>
 5 #include<cmath>
 6 #include<algorithm>
 7 #include<queue>
 8 #include<stack>
 9 #include<map>
10 using namespace std;
11 const int maxn=5e5+3;
12 typedef long long ll;
13 int a[maxn];
14 int p[maxn];
15 int pre[maxn];
16 int nxt[maxn];
17 int b[maxn];
18 int c[maxn];
19 int n,k;
20 int main()
21 {
22     int T;
23     scanf("%d",&T);
24     while(T--)
25     {
26         scanf("%d%d",&n,&k);
27         for(int i=1;i<=n;i++)
28         {
29             scanf("%d",&a[i]);
30             p[a[i]]=i;
31             pre[i]=i-1;
32             nxt[i]=i+1;
33         }
34         ll ans=0;
35         for(int i=1;i<=n;i++)
36         {
37             ll num=0;
38             int pos=p[i];
39             int cntr=0,cntl=0;
40             for(int j=pos;j<=n&&cntr<k;j=nxt[j])
41             {
42                 b[cntr++]=nxt[j]-j;    
43             } 
44             for(int j=pos;j>=1&&cntl<k;j=pre[j])
45             {
46                 if(k-1-cntl>=cntr)
47                 {
48                     cntl++;
49                     continue;
50                 }
51                 else 
52                 {
53                     c[cntl]=j-pre[j];
54                     num+=b[k-1-cntl]*c[cntl];
55                     cntl++;
56                 }
57                 
58             } 
59             ans+=num*i;
60             nxt[pre[pos]]=nxt[pos];
61             pre[nxt[pos]]=pre[pos];
62         }
63         printf("%lld\n",ans);
64     }
65     return 0;
66  } 
链表

 

【链表】2017多校训练3 HDU 6058 Kanade's sum

标签:ring   维护   can   play   区间   bsp   acm   using   时间   

原文地址:http://www.cnblogs.com/itcsl/p/7273749.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!