hdu6521 party
作者:互联网
原题入口
题解
对每一个位置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