zoukankan      html  css  js  c++  java
  • HDU 6058 Kanade's sum —— 2017 Multi-University Training 3

    Kanade's sum

    Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 2512    Accepted Submission(s): 1045

    Problem Description
    Give you an array A[1..n]of length n

    Let f(l,r,k) be the k-th largest element of A[l..r].

    Specially , f(l,r,k)=0 if rl+1<k.

    Give you k , you need to calculate nl=1nr=lf(l,r,k)

    There are T test cases.

    1T10

    kmin(n,80)

    A[1..n] is a permutation of [1..n]

    n5105
     
    Input
    There is only one integer T on first line.

    For each test case,there are only two integers n,k on first line,and the second line consists of n integers which means the array A[1..n]
     
    Output
    For each test case,output an integer, which means the answer.
     
    Sample Input
    1
    5 2
    1 2 3 4 5
     
    Sample Output
    30
     
    题目大意:给定数列A,A是1,2,...,n的一个排序,求数列中所有区间的第k小的数之和。
    思路:对于1~n的某个数 i,向左向右分别数出 k 个比 i 大的数,求得第 k 小的数是 i 的最大区间。然后在这个最大区间里,从左往右每次取k个不小于 i 的数,每一次更新区间时加上前后两个区间的差值即可。
     
    AC代码(借鉴了下网上的代码):
     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<vector>
     5 #include<algorithm>
     6 #include<fstream> 
     7 using namespace std;
     8 int a[500005];
     9 long long l[90], r[90];
    10 int main()
    11 {
    12     int T,n,k;
    13     //ifstream cin("ylq.txt");
    14     cin>>T; 
    15     while(T--)
    16     {
    17         scanf("%d %d", &n, &k);
    18         //cin>>n>>k;
    19         for(int i=1;i<=n;i++) scanf("%d", &a[i]);
    20         int t;
    21         long long ans=0;
    22         for(int i=1;i<=n;i++){
    23             t=0;
    24             l[t++]=i;
    25             int j;
    26             for(j=i-1;j>0&&t<k;j--){
    27                 if(a[j]>a[i]){
    28                     l[t++]=j;
    29                 }
    30             }
    31             long long sum=0;
    32             if(t==k)
    33             {
    34                 int tmp=1;
    35                 for(;j>0;j--){
    36                     if(a[j]<a[i]) tmp++;
    37                     else break;
    38                 }
    39                 sum+=tmp;
    40                 for(j=i+1;j<=n&&t>=0;j++){
    41                     if(a[j]<a[i]) sum+=tmp;
    42                     else{
    43                         t--;
    44                         if(t==0) break;
    45                         tmp=l[t-1]-l[t];
    46                         sum+=tmp;
    47                     }
    48                 }
    49             }
    50             else
    51             {
    52                 for(j=i+1;j<=n&&t<k;j++){
    53                     if(a[j]>a[i]) l[t++]=j;
    54                 }
    55                 if(t==k)
    56                 {
    57                     sort(l, l+t);
    58                     int tmp=l[0];
    59                     int p=0;
    60                     sum+=tmp;
    61                     for(;j<=n&&p<t;j++){
    62                         if(a[j]<a[i]) sum+=tmp;
    63                         else{
    64                             p++;
    65                             if(l[p]>i) break;    
    66                             tmp=abs(l[p]-l[p-1]);
    67                             sum+=tmp;
    68                         }
    69                         
    70                     }
    71                 }
    72             }
    73             ans+=(long long)(sum*a[i]);
    74         } 
    75         cout<<ans<<endl;
    76     }
    77 }
     
  • 相关阅读:
    echarts图表重设尺寸
    文本文档中各字母出现次数汇总(java)
    30道随机运算
    随机生成验证码
    原码,反码,补码
    动手动脑(一)
    模拟银行ATM系统(基础版)
    2018暑期周总结报告(五)
    2018暑期周总结报告(四)
    2018暑期周总结报告(三)
  • 原文地址:https://www.cnblogs.com/MasterSpark/p/7291129.html
Copyright © 2011-2022 走看看