原题入口
题解
对每一个位置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
",sm);
96 if(t>=x)T.modify(1,1,n,x,t,y);
97 }
98 }
99 return 0;
100 }