ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

hdu6521 party

2022-07-04 11:31:06  阅读:168  来源: 互联网

标签:ch lb rs int mid return hdu6521 party


原题入口

Problem - 6521 (hdu.edu.cn)

题解

对每一个位置i维护一个数组R,表示i能够到的人的最远的R,显然每个人已经认识的人是连续的,所以R是合法的。然后发现R关于i单调不减,因为如果存在i<j,且R[i]>R[j],说明存在一个操作l,r覆盖了i和j,那么i能够到的R,j也一定可以够到

答案维护就是找出区间内最大的t使得R[t]<r

$(t-l+1)*r-\sum_{i=l}^{t}R[i]$

用线段树维护求和最小值,区间修改即可

代码

  1 //对于每个人来说所认识的人必定是一段连续的区间
  2 //而且L[i],R[i]是单调递增的 
  3 //不需要吉司机线段树,因为区间修改时保证整个区间都是会被修改的 
  4 #include<bits/stdc++.h>
  5 using namespace std;
  6 #define LL long long
  7 const int MAXN=5e5+17;
  8 const int INF=1e9;
  9 inline int read(){
 10     int s=0;bool w=0;char ch=getchar();
 11     while(ch<'0'||ch>'9')w|=(ch=='-'),ch=getchar();
 12     while(ch>='0'&&ch<='9')s=s*10+ch-'0',ch=getchar();
 13     return w?-s:s;
 14 }
 15 #define kd (read())
 16 int n,m;
 17 struct segment_tree{
 18     LL sm[MAXN<<2];
 19     int mn[MAXN<<2],lb[MAXN<<2];
 20     #define ls (u<<1)
 21     #define rs (u<<1|1)
 22     inline void up(int u){
 23         sm[u]=sm[ls]+sm[rs];
 24         mn[u]=min(mn[ls],mn[rs]);
 25         return ;
 26     }
 27     inline void down(int u,int l,int r){
 28         if(l==r||lb[u]==0)return ;
 29         int mid=l+r>>1;
 30     //    cout<<"u="<<u<<" "<<l<<" "<<r<<" "<<lb[u]<<endl;
 31         if(lb[u]>lb[ls]){
 32             sm[ls]=1LL*(mid-l+1)*lb[u];
 33             mn[ls]=lb[u];
 34             lb[ls]=lb[u];
 35             //cout<<ls<<" "<<l<<" "<<mid<<" "<<lb[ls]<<" "<<mn[ls]<<endl;
 36         }
 37         if(lb[u]>lb[rs]){
 38             sm[rs]=1LL*(r-mid)*lb[u];
 39             mn[rs]=lb[u];
 40             lb[rs]=lb[u];
 41         //    cout<<rs<<" "<<mid+1<<" "<<r<<" "<<lb[rs]<<" "<<mn[rs]<<endl;
 42         }
 43     //    cout<<"EDN"<<endl;
 44         return ;
 45     }
 46     void build(int u,int l,int r){
 47         lb[u]=0;
 48         if(l==r)return sm[u]=mn[u]=l,void();
 49         int mid=l+r>>1;
 50         build(ls,l,mid),build(rs,mid+1,r);
 51         return up(u),void();
 52     }
 53     int qw_pos(int u,int l,int r,int x,int y){
 54         down(u,l,r);
 55         if(r<x)return x-1;
 56         if(l>y)return x-1;
 57         if(mn[u]>=y)return x-1;
 58         if(l==r)return l;
 59         int mid=l+r>>1;
 60         if(mn[rs]<y)return qw_pos(rs,mid+1,r,x,y);
 61         else return qw_pos(ls,l,mid,x,y);
 62     }
 63     LL qw_sm(int u,int l,int r,int x,int y){
 64         down(u,l,r);
 65         if(l>=x&&r<=y)return sm[u];
 66         int mid=l+r>>1;LL res=0;
 67         if(x<=mid)res+=qw_sm(ls,l,mid,x,y);
 68         if(y>=mid+1)res+=qw_sm(rs,mid+1,r,x,y);
 69         return res;
 70     }
 71     void modify(int u,int l,int r,int x,int y,int w){
 72         down(u,l,r);
 73         if(l>=x&&r<=y){
 74             mn[u]=lb[u]=w;
 75             sm[u]=1LL*(r-l+1)*w;
 76             return ;
 77         }
 78         int mid=l+r>>1;
 79         if(x<=mid)modify(ls,l,mid,x,y,w);
 80         if(y>=mid+1)modify(rs,mid+1,r,x,y,w);
 81         return up(u),void();
 82     }
 83 }T;
 84 int main(){
 85     freopen("data.in","r",stdin);
 86     freopen("std.out","w",stdout);
 87     while(~scanf("%d%d",&n,&m)){
 88         T.build(1,1,n);
 89         for(int i=1,x,y;i<=m;++i){
 90             x=kd,y=kd;
 91             LL sm=0;
 92             int t=T.qw_pos(1,1,n,x,y);
 93             //cout<<"t="<<t<<endl;
 94             if(t>=x)sm=1LL*(t-x+1)*y-T.qw_sm(1,1,n,x,t);
 95             printf("%lld\n",sm);
 96             if(t>=x)T.modify(1,1,n,x,t,y);
 97         }
 98     }
 99     return 0;
100 }
View Code

 

标签:ch,lb,rs,int,mid,return,hdu6521,party
来源: https://www.cnblogs.com/2018hzoicyf/p/15510152.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有