以前看着这个芳菲菲其弥章的题面以为这题又是什么数据结构神题。。。。。。
其实就是 加点横坐标单调但查询斜率不单调的斜率优化 + 时间限制 + 树上查询。
解法1(套路解法):
因为时间限制,我们用线段树维护每个小区间的凸包,最后求个最小值就行。
因为树上查询所以树链剖分。
因为这些操作常数都不是很大,时间复杂度分析出来也没啥意思。。。。
AC Code:
#include<bits/stdc++.h>
#define maxn 200005
#define inf 0x3f3f3f3f3f3f3f3f
#define LL long long
using namespace std;
char cb[1<<15],*cs=cb,*ct=cb;
#define getc() (cs==ct && (ct=(cs=cb)+fread(cb,1,1<<15,stdin),cs==ct)?0:*cs++)
template<class T>inline void read(T &res)
{
char ch;
for(;!isdigit(ch=getc()););
for(res=ch-'0';isdigit(ch=getc());res=ch-'0'+res*10);
}
int n,t;
int info[maxn],Prev[maxn],to[maxn],cnt_e;
LL cst[maxn];
inline void Node(int u,int v,LL ct){
Prev[++cnt_e]=info[u],info[u]=cnt_e,to[cnt_e]=v,cst[cnt_e]=ct; }
LL dep[maxn],p[maxn],q[maxn],l[maxn];
int fa[maxn],tp[maxn],id[maxn],bl[maxn],siz[maxn],son[maxn],tot,cnt_l;
void dfs1(int now)
{
siz[now] = 1 , son[now] = -1;
for(int i=info[now];i;i=Prev[i])
{
dep[to[i]] = dep[fa[to[i]] = now] + cst[i];
dfs1(to[i]);
siz[now] += siz[to[i]];
if(son[now] == -1 || (siz[son[now]] < siz[to[i]]))
son[now] = to[i];
}
}
void dfs2(int now)
{
id[now] = ++tot;
if(son[now]!=-1) bl[son[now]] = bl[now] , dfs2(son[now]);
for(int i=info[now];i;i=Prev[i])
if(to[i]!=son[now])
{
tp[bl[to[i]] = ++cnt_l] = to[i];
dfs2(to[i]);
}
}
struct Point
{
LL x,y;
Point(LL x=0,LL y=0):x(x),y(y){
}
double operator *(const Point &B)const
{
return (B.y-y) * 1.0 / (B.x-x);
}
};
bool flag = 0;
vector<Point>pt[maxn<<2];
LL solveseg(int now,LL K)
{
vector<Point>&p = pt[now];
if(p.size() ==