zoukankan      html  css  js  c++  java
  • cf799c 树状数组魔改

    这题的树状数组是用来维护区间最大值的!非常神奇

    第一次见到这种用法,其实和区间求和也没什么差别

    /*
    树状数组魔改版 
    有三种方案:选两种c,选两个d,选一个c一个d 
    前两种方案需要选出符合条件的魅力值最大的物品,枚举的话复杂度n*n,
    那么将每件物品按照价格升序排序,同价格时按照魅力值降序排序
    枚举每件物品,然后第二件物品就是剩下的钱可以买的魅力值最大的物品 
    */
    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long 
    #define maxn 100005
    struct C{int p,b;}c[maxn];
    struct D{int p,b;}d[maxn];
    int ans,n,C,D,p,b,totc,totd;
    char s[10];
    int bit[maxn];
    void update(int x,int val){
        while(x<=maxn-2){
            bit[x]=max(val,bit[x]);
            x+=x&-x;
        }
    }
    int query(int x){
        int res=0;
        while(x){
            res=max(res,bit[x]);
            x-=x&-x;
        }
        return res;
    }
    int main(){
        totc=totd=ans=0;
        scanf("%d%d%d",&n,&C,&D);
        for(int i=1;i<=n;i++){
            scanf("%d%d%s",&b,&p,s);
            if(s[0]=='C' && p<=C)c[++totc].p=p,c[totc].b=b;
            else if(s[0]=='D' && p<=D)d[++totd].p=p,d[totd].b=b; 
        }
        
        int max1=-1,max2=-1;
        for(int i=1;i<=totc;i++)max1=max(max1,c[i].b);
        for(int i=1;i<=totd;i++)max2=max(max2,d[i].b);
        if(max1+1 && max2+1) ans=max(ans,max1+max2); 
    
        memset(bit,0,sizeof bit); 
        for(int i=1;i<=totc;i++){
            int tmp=query(C-c[i].p);
            if(tmp>0)
                ans=max(ans,c[i].b+tmp);
            
            update(c[i].p,c[i].b);
        }
        
        memset(bit,0,sizeof bit);
        for(int i=1;i<=totd;i++){
            int tmp=query(D-d[i].p);
            if(tmp>0)
                ans=max(ans,d[i].b+tmp);
    
            update(d[i].p,d[i].b);
        }
        printf("%d
    ",ans);
    }
  • 相关阅读:
    Java中间件:淘宝网系统高性能利器(转)
    淘宝的数据库拆分(TDDL)(转)
    java web几种开发模式(转)
    C++模板【转】
    set[c++]
    C# jsonhelper
    Vector[C++]
    list[C++]
    map[C++]
    C[泊车管理系统]
  • 原文地址:https://www.cnblogs.com/zsben991126/p/10244232.html
Copyright © 2011-2022 走看看