zoukankan      html  css  js  c++  java
  • codeforces 1180E Serge and Dining Room 线段树

    题目传送门

    题目大意:

      给出a序列和b序列,a序列为各种食物的价格,b序列为一列排着队的小朋友拥有的钱,小朋友依次购买食物,每个人都买自己能买的起的最贵的食物,买不起就离开队伍。给出q次操作,操作1是修改食物的价格,操作2是修改小朋友的钱,每次操作后询问当小朋友买完之后,能买到的最贵的食物的价格是多少,没有食物了就输出-1.

    思路:

      首先,小朋友的顺序对最终答案没有任何影响,因为如果两个小朋友能买两个东西,这两个小朋友无论怎么换,都是能买的了的。

      其次,对于一个价格为x的物品,如果有一个钱大于等于x的小朋友,就可以买走这个物品。如果我们把价格想象成一条数轴,那么物品就是1,小朋友就是-1,价格或者钱就是坐标轴的位置,这道题就转化成了求最大的后缀和大于等于1的下标。

      最后,我们用线段树来维护这个值,注意用线段树维护最大后缀和时,在查询时要注意后面的区间的影响。

    #include<bits/stdc++.h>
    #define clr(a,b) memset(a,b,sizeof(a))
    using namespace std;
    typedef long long ll;
    const int maxn=1000010;
    int n,m,q;
    int sum[maxn<<2],maxx[maxn<<2];
    int a[maxn],b[maxn];
    void update(int o,int l,int r,int p,int val){
        if(l==r){
            sum[o]+=val;
            maxx[o]+=val;
            return;
        }
        int mid=(l+r)>>1;
        if(p<=mid)update(o<<1,l,mid,p,val);
        else update(o<<1|1,mid+1,r,p,val);
        sum[o]=sum[o<<1]+sum[o<<1|1];
        maxx[o]=max(maxx[o<<1|1],maxx[o<<1]+sum[o<<1|1]);
        //这里的每一个maxx,都是对应的 区间最大后缀和  但不是整根数轴的最大后缀和。 
    }
    struct node{
        int max,sum;
    };
    int query(int o,int l,int r,node tep){
        if(l==r){
            return l;
        }
        int mid=(l+r)>>1;
        node tep2;
        tep2.sum=tep.sum+sum[o<<1|1];
        tep2.max=maxx[o<<1|1]+tep.sum;//将 标号为o这段区间的后面一段(o+1)的影响合并到o区间中 
        if(tep2.max>0){
            return query(o<<1|1,mid+1,r,tep);
        }
        else {
            return query(o<<1,l,mid,tep2);
        }
    }
    int main(){
        while(cin>>n>>m){
            clr(sum,0),clr(maxx,0);
            for(int i=1;i<=n;i++){
                scanf("%d",&a[i]);
                update(1,1,maxn-1,a[i],1);
            }
            for(int i=1;i<=m;i++){
                scanf("%d",&b[i]);
                update(1,1,maxn-1,b[i],-1);
            }
            cin>>q;
            while(q--){
                int op,pos,val;
                scanf("%d%d%d",&op,&pos,&val);
                if(op==1){
                    update(1,1,maxn-1,a[pos],-1);
                    update(1,1,maxn-1,a[pos]=val,1);
                }else{
                    update(1,1,maxn-1,b[pos],1);
                    update(1,1,maxn-1,b[pos]=val,-1);
                }
                
                if(maxx[1]<=0)puts("-1");
                else printf("%d
    ",query(1,1,maxn-1,{0,0}));
    
            }
        }
    }
  • 相关阅读:
    11.重写、抽象、接口、异常
    3.用户组、指令运行级别、帮助指令、文件目录类(一)
    2.vi和vim编辑器、vi和vim三种模式、vi和vim快捷键、关机、重启命令、用户管理
    1.VM和Linux系统(centos)安装、linux目录结构、远程登录到Linux服务器、远程上传下载文件xftp
    10.函数、流程控制
    9.变量、存储过程
    8.事务、视图
    7.库和表的管理、常见数据类型、常见约束、标识符
    CH6801 棋盘覆盖(二分图最大匹配)
    洛谷P1525 关押罪犯(二分图判定+二分)
  • 原文地址:https://www.cnblogs.com/mountaink/p/11093645.html
Copyright © 2011-2022 走看看