NOI 2014 购票 (树上各种科技)

这篇博客探讨了NOI 2014竞赛中涉及的购票问题,该问题看似复杂,实则结合了横坐标单调的斜率优化、时间限制和树上查询的元素。通过线段树维护区间凸包和树链剖分来解决,同时也提到了点分治和二进制分组的解法,最终实现AC代码。
摘要由CSDN通过智能技术生成

以前看着这个芳菲菲其弥章的题面以为这题又是什么数据结构神题。。。。。。
其实就是 加点横坐标单调但查询斜率不单调的斜率优化 + 时间限制 + 树上查询。
解法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() == 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值