首页 > 其他 > 详细

【HDU6609】Find the answer

时间:2019-07-30 17:17:40      阅读:104      评论:0      收藏:0      [点我收藏+]

技术分享图片

题目大意:给你一个序列,对于每个i,你可以选择1~i-1中任意多的数并将它删去,剩余的数(包括i)∑≤m,问对于每个i最少删几个数可以达到要求

题解:

考虑朴素的思想,对于每个i,我只需要删去最大的若干个使得∑≤m即可,时间复杂度O(n^2)

显然不可接受,考虑优化

显然可以看出,因为只需要删去最大的若干数,于是想到前K大,于是很自然想到用线段树

先离散化,只需要记录这个数是第几大,之后线段树维护区间和,每新加入一个点时加入这个点第几大的下标

询问时在线段树上二分出前K大即可,时间复杂度O(nlogn)

代码:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<string>
#define ll long long
using namespace std;
int TT,n;
int ans[200001];
ll m;
struct node
{
    ll v;
    int bh,rk;
}a[200001];
bool cmp(const node &T1,const node &T2){return T1.v<T2.v;}
bool cmp2(const node &T1,const node &T2){return T1.bh<T2.bh;}
ll sum[200001*5],cnt[200001*5];
int ask(int l,int r,ll v,int pos,ll tot)
{
    if(sum[pos]+tot<=v)return cnt[pos];
    else
    {
      int mid=l+r>>1;
      int t=ask(l,mid,v,pos<<1,tot);
      if(t==cnt[pos<<1])t+=ask(mid+1,r,v,pos<<1|1,tot+sum[pos<<1]);
      return t;
    }
}
void insert(int l,int r,ll v,int p,int pos)
{
    if(l==r && l==p)
    {
      sum[pos]=v;cnt[pos]=1;
      return;
    }
    int mid=l+r>>1;
    if(p<=mid)insert(l,mid,v,p,pos<<1);
    else insert(mid+1,r,v,p,pos<<1|1);
    sum[pos]=sum[pos<<1]+sum[pos<<1|1];
    cnt[pos]=cnt[pos<<1]+cnt[pos<<1|1];
}
int main()
{
    scanf("%d",&TT);
    while(TT--)
    {
      memset(sum,0,sizeof(sum));
      memset(cnt,0,sizeof(cnt));
      memset(ans,0,sizeof(ans));
      scanf("%d%lld",&n,&m);
      for(int i=1;i<=n;i++){scanf("%lld",&a[i].v);a[i].bh=i;}
      sort(a+1,a+1+n,cmp);
      for(int i=1;i<=n;i++)a[i].rk=i;
      sort(a+1,a+1+n,cmp2);
      for(int i=1;i<=n;i++)
      {
        int t=ask(1,n,m-a[i].v,1,0);
        ans[i]=i-1-t;
        insert(1,n,a[i].v,a[i].rk,1);
      }
      for(int i=1;i<=n;i++)printf("%d ",ans[i]);
      printf("\n");
    }
    return 0;
}

心得:考场上很自然的想到,说明该部分知识掌握不错,继续加油

【HDU6609】Find the answer

原文:https://www.cnblogs.com/worcher/p/11271148.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!