zoukankan      html  css  js  c++  java
  • 多校3 Find the answer hdu6609 贪心 权值线段树

    题意:Q组样例。每组样例第一行给出n、m,接下来一行n个数(a[i])。对于每一个  i  ,输出需要删除最少的个数,使得 a[i]+  sum_{j=1}^{i-1}a[i]<=m

    如果每次都从大到小删除肯定是会超时的   但是有些是可以永久删除的 

    当set里面大于m 的时候    最大的数是肯定要删除的!( 贪心) 

    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define ll long long
    #define see(x) (cerr<<(#x)<<'='<<(x)<<endl)
    #define pb push_back
    #define inf 0x3f3f3f3f
    #define CLR(A,v)  memset(A,v,sizeof A)
    typedef pair<int,int>pii;
    //////////////////////////////////
    const int N=2e6+10;
    int n,m,a[N],sum,sumtemp,cnt,temp;
    
    int main()
    {
        int cas;scanf("%d",&cas);
        while(cas--)
        {
            scanf("%d%d",&n,&m);
            rep(i,1,n)scanf("%d",&a[i]);
    
            multiset<int>q;
            cnt=sumtemp=sum=temp=0;
            rep(i,1,n)
            {
                temp=0;
                sumtemp=sum;
                auto j=q.end();
                while(sumtemp+a[i]>m)
                {
                    --j;
                    sumtemp-=*j;
                    temp++;
                }
                printf("%d ",cnt+temp);
    
                q.insert(a[i]);sum+=a[i];
                j=q.end();
                while(sum>m)
                {
                    --j;
                    sum-=*j;
                    q.erase(q.find(*j));
                    cnt++;
                }
            }
            printf("
    ");
        }
        return 0;
    }
    View Code

    权值线段树:

    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define ll long long
    #define see(x) (cerr<<(#x)<<'='<<(x)<<endl)
    #define pb push_back
    #define inf 0x3f3f3f3f
    #define CLR(A,v)  memset(A,v,sizeof A)
    typedef pair<int,int>pii;
    //////////////////////////////////
    const int N=2e6+10;
    
    #define lson l,m,pos<<1
    #define rson m+1,r,pos<<1|1
    
    ll t[N];
    int num[N],n,m,a[N],b[N];
    
    void build(int l,int r,int pos)
    {
        t[pos]=0;num[pos]=0;
        if(l==r)return ;
        int m=(l+r)>>1;
        build(lson);build(rson);
    }
    
    void upnode(int x,int l,int r,int pos)
    {
        if(l==r){ num[pos]++;t[pos]+=b[x];return;};
        int m=(l+r)>>1;
        if(x<=m)upnode(x,lson);
        else upnode(x,rson);
        t[pos]=t[pos<<1]+t[pos<<1|1];
        num[pos]=num[pos<<1]+num[pos<<1|1];
    }
    
    int qsum(int x,int l,int r,int pos)
    {
        if(t[pos]<=x)return num[pos];
        if(l==r)return min(num[pos],x/b[l]);
        int m=(l+r)>>1;
        if(t[pos<<1]>=x) return qsum(x,lson);
        else return num[pos<<1]+qsum(x-t[pos<<1],rson);
    }
    int main()
    {
        int cas;scanf("%d",&cas);
        while(cas--)
        {
            scanf("%d%d",&n,&m);
            rep(i,1,n)scanf("%d",&a[i]),b[i]=a[i];
    
            sort(b+1,b+1+n);
    
            int nn=unique(b+1,b+1+n)-b-1;
            build(1,nn,1);
            rep(i,1,n)
            {
                if(i==1)printf("0 ");
                else printf("%d ",i-1-qsum(m-a[i],1,nn,1));
                int pos=lower_bound(b+1,b+1+n,a[i])-b;
                upnode(pos,1,nn,1);
            }
            printf("
    ");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    程序员自我【营销】,如何打造个人【品牌】
    程序员应该怎样和领导相处?
    程序员必备能力——晋升之道
    聊一聊 软件系统中的“热力学第二定律”
    程序员如何利用技术管理技巧
    技术人必须掌握能力——深度思考
    程序员逆袭之路——系列文章更新中
    程序员跳槽,该如何选择一家好公司
    C++-运行时类型信息,异常(day11)
    C++-多态,纯虚函数,抽象类,工厂模式,虚析构函数(day10)
  • 原文地址:https://www.cnblogs.com/bxd123/p/11270388.html
Copyright © 2011-2022 走看看