题目大意:给你两个大小为n的三元组集合
S
1
=
{
(
L
i
,
R
i
,
v
i
)
∣
i
∈
[
1
,
n
]
}
S_1=\{(L_i,R_i,v_i)|i\in[1,n]\}
S1={(Li,Ri,vi)∣i∈[1,n]}和
S
2
=
{
(
A
i
,
B
i
,
c
i
)
∣
i
∈
[
1
,
n
]
}
S_2=\{(A_i,B_i,c_i)|i\in[1,n]\}
S2={(Ai,Bi,ci)∣i∈[1,n]},你要选出
(
L
,
R
,
v
)
∈
S
1
,
(
A
,
B
,
c
)
∈
S
2
(L,R,v)\in S_1,(A,B,c)\in S_2
(L,R,v)∈S1,(A,B,c)∈S2,使得
(
r
−
l
+
1
)
v
c
(r-l+1)vc
(r−l+1)vc最小,其中
[
l
,
r
]
[l,r]
[l,r]表示
[
L
,
R
]
[L,R]
[L,R]和
[
A
,
B
]
[A,B]
[A,B]的交集。
R
,
B
,
n
≤
1
0
5
R,B,n\le10^5
R,B,n≤105。
题解:
首先一个区间包含另一个的情况可以直接扫描线求。
否则枚举
(
A
,
B
,
c
)
(A,B,c)
(A,B,c),不妨设某个
(
L
,
R
,
v
)
(L,R,v)
(L,R,v)满足
L
≤
A
≤
R
≤
B
L\le A\le R\le B
L≤A≤R≤B,那么算出来是
(
R
+
1
−
A
)
v
c
=
c
[
(
−
v
)
A
+
(
R
+
1
)
v
]
(R+1-A)vc=c[(-v)A+(R+1)v]
(R+1−A)vc=c[(−v)A+(R+1)v],相当于每个
(
L
,
R
,
v
)
(L,R,v)
(L,R,v)维护一条线段,当
x
∈
[
L
,
R
]
x\in[L,R]
x∈[L,R]时能够取到
(
−
v
)
x
+
(
R
+
1
)
v
(-v)x+(R+1)v
(−v)x+(R+1)v的函数值。这是一个经典的李超树问题。
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define Rep(i,v) rep(i,0,(int)v.size()-1)
#define lint long long
#define ull unsigned lint
#define db long double
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define debug(x) cerr<<#x<<"="<<x
#define sp <<" "
#define ln <<endl
using namespace std;
typedef pair<int,int> pii;
typedef set<int>::iterator sit;
namespace INPUT_SPACE{
const int BS=(1<<24)+5;char Buffer[BS],*HD,*TL;inline int gc() { if(HD==TL) TL=(HD=Buffer)+fread(Buffer,1,BS,stdin);return (HD==TL)?EOF:*HD++; }
inline int inn() { int x,ch;while((ch=gc())<'0'||ch>'9');x=ch^'0';while((ch=gc())>='0'&&ch<='9') x=(x<<1)+(x<<3)+(ch^'0');return x; }
}using INPUT_SPACE::inn;
const int N=100010;const int m=1e5;
int L[N],R[N],v[N],A[N],B[N],c[N];
struct P{
int l,r,v;P(int _l=0,int _r=0,int _v=0) { l=_l,r=_r,v=_v; }
inline bool operator<(const P &p)const { return r<p.r; }
}p[N],q[N];
namespace CONT_space{
struct segment{
int l,r;lint v;
segment *ch[2];
}*rt;
inline int build(segment* &rt,int l,int r)
{
rt=new segment,rt->l=l,rt->r=r,rt->v=0;int mid=(l+r)>>1;if(l==r) return 0;
return build(rt->ch[0],l,mid),build(rt->ch[1],mid+1,r);
}
inline int update(segment* &rt,int p,lint v)
{
int l=rt->l,r=rt->r,mid=(l+r)>>1;rt->v=max(rt->v,v);
if(l==r) return 0;return update(rt->ch[p>mid],p,v);
}
inline lint query(segment* &rt,int s,int t)
{
int l=rt->l,r=rt->r,mid=(l+r)>>1;
if(s<=l&&r<=t) return rt->v;lint ans=0;
if(s<=mid) ans=max(ans,query(rt->ch[0],s,t));
if(mid<t) ans=max(ans,query(rt->ch[1],s,t));
return ans;
}
inline lint cont(int n)
{
rep(i,1,n) p[i]=P(L[i],R[i],v[i]),q[i]=P(A[i],B[i],c[i]);
sort(p+1,p+n+1),sort(q+1,q+n+1);lint ans=0;build(rt,1,m);
for(int i=1,j=0;i<=n;i++)
{
int a=q[i].l,b=q[i].r;
while(j<n&&p[j+1].r<=b) j++,update(rt,p[j].l,(p[j].r-p[j].l+1ll)*p[j].v);
ans=max(ans,query(rt,a,b)*q[i].v);
}
return ans;
}
}using CONT_space::cont;
namespace SOLVE_space{
const lint inf=-1e16;
struct Line{
lint k,b;
Line(lint _k=0,lint _b=inf) { k=_k,b=_b; }
inline lint operator()(int x) { return k*x+b; }
};
struct segment{
int l,r;Line L;
segment *ch[2];
}*rt;
inline int build(segment* &rt,int l,int r)
{
rt=new segment,rt->l=l,rt->r=r;int mid=(l+r)>>1;if(l==r) return 0;
return build(rt->ch[0],l,mid),build(rt->ch[1],mid+1,r);
}
inline int update(segment* &rt,Line L)
{
int l=rt->l,r=rt->r,mid=(l+r)>>1;
if(rt->L(l)<L(l)) swap(rt->L,L);
if(rt->L(r)>=L(r)) return 0;
if(rt->L(mid)>=L(mid)) update(rt->ch[1],L);
else swap(rt->L,L),update(rt->ch[0],L);
return 0;
}
inline int update(segment* &rt,int s,int t,const Line &L)
{
int l=rt->l,r=rt->r,mid=(l+r)>>1;
if(s<=l&&r<=t) return update(rt,L);
if(s<=mid) update(rt->ch[0],s,t,L);
if(mid<t) update(rt->ch[1],s,t,L);
return 0;
}
inline lint query(segment* &rt,int p)
{
int l=rt->l,r=rt->r,mid=(l+r)>>1;lint ans=rt->L(p);
if(l==r) return ans;return max(ans,query(rt->ch[p>mid],p));
}
inline lint solve(int n)
{
rep(i,1,n) p[i]=P(L[i],R[i],v[i]),q[i]=P(A[i],B[i],c[i]);
sort(p+1,p+n+1),sort(q+1,q+n+1);lint ans=0;build(rt,1,m);
for(int i=1,j=0;i<=n;i++)
{
while(j<n&&p[j+1].r<=q[i].r)
j++,update(rt,p[j].l,p[j].r,Line(-p[j].v,p[j].v*(p[j].r+1ll)));
lint res=query(rt,q[i].l);if(res>0) ans=max(ans,res*q[i].v);
}
return ans;
}
}using SOLVE_space::solve;
#define rev(x) x=m-x+1
int main()
{
int n=inn();
rep(i,1,n) L[i]=inn(),R[i]=inn(),v[i]=inn();
rep(i,1,n) A[i]=inn(),B[i]=inn(),c[i]=inn();
lint ans=max(cont(n),solve(n));
rep(i,1,n) swap(L[i],A[i]),swap(B[i],R[i]),swap(v[i],c[i]);
ans=max(ans,max(cont(n),solve(n)));
return !printf("%lld\n",ans);
}