zoukankan      html  css  js  c++  java
  • HDU 6609 Find the answer(权值线段树+二分)

    题目链接

    题解思路:对于每个位置,求出需要减掉的数 然后在权值线段树上进行二分找答案。

    #include<bits/stdc++.h>
    
    using namespace std;
    
    #define maxn 200005
    #define ll long long
    #define ls l,mid,rt<<1
    #define rs mid+1,r,rt<<1|1
    typedef pair<int,int> PII;
    const int mod = 1e9+7;
    
    int n,m;
    ll a[maxn],b[maxn],num[maxn<<2],sum[maxn<<2],atag[maxn<<2];
    
    void Pushup(int rt){
        sum[rt]=sum[rt<<1]+sum[rt<<1|1];
        num[rt]=num[rt<<1]+num[rt<<1|1];
    }
    
    void Build(int l,int r,int rt){
        num[rt]=sum[rt]=0;
        if(l==r)return ;
        int mid=(l+r)>>1;
        Build(ls);
        Build(rs);
    }
    
    void Update(int l,int r,int rt,int pos){
        if(l==r&&l==pos){
            sum[rt]+=b[pos];
            num[rt]++;
            return ;
        }
        int mid=(l+r)>>1;
        if(pos<=mid)Update(ls,pos);
        else Update(rs,pos);
        Pushup(rt);
    }
    
    int Query(int l,int r,int rt,ll ss){
        if(l==r){
            int ans=ss/b[l];
            if(ss%b[l])ans++;
            return ans;
        }
        int mid=(l+r)>>1;
        if(sum[rt<<1|1]>=ss)return Query(rs,ss);
        else{
            int ans=num[rt<<1|1];
            ans+=Query(ls,ss-sum[rt<<1|1]);
            return ans;
        }
    }
    
    int main()
    {
        int t;cin>>t;
        while(t--){
            scanf("%d %d",&n,&m);
            for(int i=1;i<=n;i++){
                scanf("%lld",&a[i]);
                b[i]=a[i];
            }
            sort(b+1,b+n+1);
            int nn=unique(b+1,b+n+1)-(b+1);
            Build(1,nn,1);
            ll Sum=0;
            for(int i=1;i<=n;i++){
                Sum+=a[i];
                if(Sum<=m){
                    printf("0 ");
                    int pos=lower_bound(b+1,b+nn+1,a[i])-b;
                    Update(1,nn,1,pos);
                }
                else{
                    ll ss=Sum-m;
                    printf("%d ",Query(1,nn,1,ss));
                    int pos=lower_bound(b+1,b+nn+1,a[i])-b;
                    Update(1,nn,1,pos);
                }
            }
            printf("
    ");
        }
    }
  • 相关阅读:
    PHP页面跳转的几种方法
    PHP网站并发测试
    04-上传文件
    01-转>linux命令
    01-CDN的好处
    05-socket.io使用
    04-soket.io使用2 -数据同步简单聊天室效果
    03-socket.io 2.3.0版本的使用-用户请求接口,实时推送给前端数据
    02-转>
    跨域-转>预解析OPTIONS请求
  • 原文地址:https://www.cnblogs.com/Mmasker/p/11917469.html
Copyright © 2011-2022 走看看