E - Serge and Dining Room

https://codeforces.com/contest/1180/problem/E

转载自他人博客

题意
nn个菜肴,有mm个小朋友,每个菜肴的价格为aiai,每个小朋友有bibi元钱,小朋友从1m1→m依次购买菜肴,当第ii个小朋友轮到的时候,他会购买他买的起的最贵的,否则就离开。
要求支持修改第ii个菜肴的价格和修改第ii个小朋友的拥有的钱数的两种操作,每次操作完成给出mm个小朋友买完后剩下的最贵的菜肴的价格是多少。

思路
假设价格大于xx的yy个菜肴都被买了,那么显然拥有钱数x≥x的小朋友个数一定要y≥y,显然如何购买是无所谓的。
那么就在aiai处减一,bibi处加一,每次询问一个最大的ll使得[l,][l,∞]的最大后缀和>0>0。
线段树维护即可。

代码

 1 #include<bits/stdc++.h>
 2 #define clr(a,b) memset(a,b,sizeof(a))
 3 using namespace std;
 4 typedef long long ll;
 5 const int maxn=1000010;
 6 int n,m,q;
 7 int sum[maxn<<2],maxx[maxn<<2];
 8 int a[maxn],b[maxn];
 9 void update(int o,int l,int r,int p,int val){
10     if(l==r){
11         sum[o]+=val;
12         maxx[o]+=val;
13         return;
14     }
15     int mid=(l+r)>>1;
16     if(p<=mid)update(o<<1,l,mid,p,val);
17     else update(o<<1|1,mid+1,r,p,val);
18     sum[o]=sum[o<<1]+sum[o<<1|1];
19     maxx[o]=max(maxx[o<<1|1],maxx[o<<1]+sum[o<<1|1]);
20     //这里的每一个maxx,都是对应的 区间最大后缀和  但不是整根数轴的最大后缀和。 
21 }
22 struct node{
23     int max,sum;
24 };
25 int query(int o,int l,int r,node tep){
26     if(l==r){
27         return l;
28     }
29     int mid=(l+r)>>1;
30     node tep2;
31     tep2.sum=tep.sum+sum[o<<1|1];
32     tep2.max=maxx[o<<1|1]+tep.sum;//将标号为o这段区间的后面一段(o+1)的影响合并到o区间中 
33     if(tep2.max>0){
34         return query(o<<1|1,mid+1,r,tep);
35     }
36     else{
37         return query(o<<1,l,mid,tep2);
38     }
39 }
40 int main(){
41     while(cin>>n>>m){
42         clr(sum,0),clr(maxx,0);
43         for(int i=1;i<=n;i++){
44             scanf("%d",&a[i]);
45             update(1,1,maxn-1,a[i],1);
46         }
47         for(int i=1;i<=m;i++){
48             scanf("%d",&b[i]);
49             update(1,1,maxn-1,b[i],-1);
50         }
51         cin>>q;
52         while(q--){
53             int op,pos,val;
54             scanf("%d%d%d",&op,&pos,&val);
55             if(op==1){
56                 update(1,1,maxn-1,a[pos],-1);
57                 update(1,1,maxn-1,a[pos]=val,1);
58             }else{
59                 update(1,1,maxn-1,b[pos],1);
60                 update(1,1,maxn-1,b[pos]=val,-1);
61             }
62             if(maxx[1]<=0)puts("-1");
63             else printf("%d\n",query(1,1,maxn-1,{0,0}));
64         }
65     }
66 }

猜你喜欢

转载自www.cnblogs.com/pangbi/p/12240896.html
今日推荐