hdu 3415 堆优化

来源:互联网 发布:stc单片机价格 编辑:程序博客网 时间:2024/06/09 19:31

//2523048 2010-06-07 13:40:55 Accepted 3415 453MS 4992K 1613 B C++ T&T
//用堆优化循环  看了别人的程序才知道
//直接用循环复杂度为o(n*k) 是TLE
#include<iostream>
#include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
struct node{
 int head,max; 
};
bool operator <(node a,node b)
{
 if(a.max != b.max)
 {
  return a.max > b.max;
 }
 else
 {
  return a.head < b.head;
 }

}
 //int hash[100005];
 int num[200005];
 int sum[100005];
int main()
{
 
 int i,j;
 int ri,rj;
 int n,k,t,sumtemp,endsum,endi,endj;
 scanf("%d",&t);
 while(t--)
 { 
 
  priority_queue<node> q;
  memset(sum,0,sizeof(sum));
  sumtemp = 0;
  endsum = -0x7ffffff;
  endi = 0;
  endj = n + k;
  scanf("%d%d",&n,&k);
  for(i = 1; i <= n; i++)
  {
   scanf("%d",&num[i]);
   sumtemp += num[i];
   sum[i] = sumtemp;
  }
  for(j = 1; j <= k; j++)
  {
   num[i] = num[j];
   sumtemp += num[i];
   sum[i] =  sumtemp;
   i++; 
  }                    //初始化sum里面的值
  node N;
  N.head = 0;
  N.max = 0;
  q.push(N);
  for(i = 1; i <= n + k; i++)
  {   
   N = q.top();  //先不出队列  直到取出的数下标和i的差大于k的时候出队列 这样所有的数只是各进出队列一次所以时间复杂度为o(n)
   while(i - N.head > k)  //减K是第前k 加 1个数
   {
    q.pop();
    if(!q.empty())
    {
     N = q.top();
    }
    else
    {
     break;
    }
   }
   if(!q.empty())  
   {
    sumtemp = sum[i] - sum[N.head]; // 这样sum[i] - sum[j]就刚好是j+1个元素加到i的和了
   }
   else  //为空的时候就是元素取完取到i - 1这样 相减就是num[i]下标为i
   {
    sumtemp = num[i];
    N.head = i - 1;//本来应该是i因为要配合后面 统一 加1好处理点
   }
   if(sumtemp > endsum)
   {
    endsum = sumtemp;
    endj = i;
    endi = N.head + 1;  //加1
   }
   else if(sumtemp == endsum && i - N.head < endj - endi)
   {
    endi = N.head + 1;//加1
    endj = i;
   }
   N.max = sum[i];
   N.head = i;
   q.push(N); 
  
  }  
  if(endj > n)
  {
   endj -= n;
  }
  if(endi > n)
  {
   endi -= n;
  }
   printf("%d %d %d/n",endsum,endi,endj);
  
 }
}

原创粉丝点击