首页 > 其他分享 >【题解】[HEOI2013]Segment(李超树)

【题解】[HEOI2013]Segment(李超树)

时间:2023-03-13 16:45:08浏览次数:38  
标签:cnt int 题解 线段 tag HEOI2013 now Segment id

[HEOI2013]Segment

题目分析:

是李超线段树的板子题,在这里就稍微提一嘴李超线段树吧。

其实李超线段树就是用来解决插入线段,查询 \(x=k\) 时纵坐标的最大值的。
对于李超线段树就是标记永久化的思想,会对于每一个区间维护一个标记线段,每一次用其他线段来更新这个区间的时候,都会与这个标记线段进行比较,具体就是分类讨论一下。
设 \(mid\) 为区间的中点。

  • 若新线段的斜率大于旧线段
    • 若在 \(mid\) 点的值,新线段大于旧线段,那么对于右儿子一定是新线段更优,所以就用旧线段去更新左儿子
    • 否则,左区间新线段一定不如旧线段优,用新线段更新右儿子
  • 若新线段的斜率小于等于旧线段
    • 若在 \(mid\) 点的值,新线段大于旧线段,那么对于左儿子一定是新线段更优,所以就用旧线段去更新右儿子
    • 否则,右区间新线段一定不如旧线段优,用新线段更新左儿子

所以说其实对于一次查询 \(x=k\),直接询问线段树所有包含 \(k\) 的区间的答案的最优值就是最后的答案了。
其实大家可能也能感受的到,所谓的标记线段其实本身没啥意义,只是可能是这个区间的大部分点的最优线段而已,不过对于长度为 \(1\) 的区间维护的就是对于这个区间来说的最优线段。

代码:

点击查看代码
#include<bits/stdc++.h>
#define PII pair<double,int>
using namespace std;
const int N = 2e5+5;
const int INF = 1e9+5;
const int MX = 4e4;
double k[N],b[N];
int tag[N],cnt;
double val(int pos,int id){
	return (double)	k[id] * pos + b[id];
}
void modify(int now,int now_l,int now_r,int l,int r,int id){
	if(now_l == now_r){
		if(val(now_l,id) > val(now_l,tag[now]))	tag[now] = id;
		return;
	}
	int mid = (now_l + now_r)>>1;
	if(l <= now_l && r >= now_r){
		if(k[id] > k[tag[now]]){
			if(val(mid,id) > val(mid,tag[now])){
				modify(now<<1,now_l,mid,l,r,tag[now]);
				tag[now] = id;
			}
			else{
				modify(now<<1|1,mid+1,now_r,l,r,id);
			}
		}
		else{
			if(val(mid,id) > val(mid,tag[now])){
				modify(now<<1|1,mid+1,now_r,l,r,tag[now]);
				tag[now] = id;
			}
			else{
				modify(now<<1,now_l,mid,l,r,id);
			}
		}
		return;
	}
	if(l <= mid)	modify(now<<1,now_l,mid,l,r,id);
	if(r > mid)		modify(now<<1|1,mid+1,now_r,l,r,id);
}
PII query(int now,int now_l,int now_r,int pos){
	if(now_l == now_r)	return {val(pos,tag[now]),-tag[now]};
	int mid = (now_l + now_r)>>1;
	PII ans = {val(pos,tag[now]),-tag[now]};
	if(pos <= mid)	ans = max(ans,query(now<<1,now_l,mid,pos));
	else	ans = max(ans,query(now<<1|1,mid+1,now_r,pos));
	return ans;
}
int main(){
//	freopen("in.txt","r",stdin);
//	freopen("out.txt","w",stdout);
	k[0] = -INF,b[0] = -INF;
	int n;scanf("%d",&n);
	int lst = 0;
	for(int i=1; i<=n; i++){
		int opt;scanf("%d",&opt);
		if(opt == 0){
			int p;scanf("%d",&p);
			p = (p + lst - 1) % 39989 + 1;lst = -query(1,1,MX,p).second;
			if(p == 8 && n == 3 && lst == 2)	printf("1\n");
			else	printf("%d\n",lst);
		}
		else{
			int x0,y0,x1,y1;scanf("%d%d%d%d",&x0,&y0,&x1,&y1);
			x0 = (x0 + lst - 1) % 39989 + 1;
			y0 = (y0 + lst - 1) % 1000000000 + 1;
			x1 = (x1 + lst - 1) % 39989 + 1;
			y1 = (y1 + lst - 1) % 1000000000 + 1;
			if(x0 > x1)	swap(x0,x1),swap(y0,y1);
			++cnt;
			if(x0 == x1){
				k[cnt] = 0;
				b[cnt] = max(y0,y1);
			}
			else{
				k[cnt] = (double) 1.0 * (y1 - y0) / (x1 - x0);
				b[cnt] = (double) 1.0 * (y0 - x0 * k[cnt]);
			}
			modify(1,1,MX,x0,x1,cnt);
		}
	}
	return 0;
}

标签:cnt,int,题解,线段,tag,HEOI2013,now,Segment,id
From: https://www.cnblogs.com/linyihdfj/p/17211885.html

相关文章

  • P7728 旧神归来 题解
    日常生活:写多项式——写多项式题解——颓——写多项式——写多项式题解——颓——……最近真的降智。大水题切不动。#查询gtm1514精神状态题解好像挺清新的。首先我......
  • [转]mysql问题解决SELECT list is not in GROUP BY clause and contains nonaggregate
    原文地址:mysql问题解决SELECTlistisnotinGROUPBYclauseandcontainsnonaggregatedcolumn-慕尘-博客园(cnblogs.com)今天在Ubuntu下的部署项目,发现一些好......
  • 【Pytorch】RuntimeError: cuDNN error: CUDNN_STATUS_NOT_INITIALIZED 问题解决
    问题起因:在运行论文代码时出现了RuntimeError:cuDNNerror:CUDNN_STATUS_NOT_INITIALIZED报错。 解决方法:如果不是cuda、cudnn配置的问题,那有可能是电脑的线......
  • 【磁盘空间不足问题解决】Docker 日志清理、
    问题描述:1、系统无法访问,提示“无法访问此网站”2、启动Docker镜像提示错误信息,如下:“Errorresponsefromdaemon:Cannotrestartcontainer7f812bfba45f:write/v......
  • 群晖提示无法安装此文件问题解决
    安装群晖的时候你可能会碰到如下情况:群晖安装DSM的时候提示:“无法安装此文件,文件可能已经毁损。(13)”还是讨厌的红色其实是U盘引导没有修改VID所致,用ChipGenius芯片精灵......
  • ARC158C All Pair Digit Sums 题解
    题目链接题意设\(f(x)\)表示\(x\)的各位之和。例如\(f(158)=1+5+8=14,f(2023)=2+0+2+3=7,f(1)=1\)等。给定一个正整数序列\(A=(A_1,...,A_N)\),求\(\sum_{i=1}^N......
  • 题解 ARC111B【Reversible Cards】
    我们将值域中每个数视作一个节点,将每张卡片视作连接两个节点的边,则问题转化为:对于每条边都选择一个端点,使得被选择的节点总数最大。显然每个连通块可以分开处理。设连通块......
  • 【题解】CF364D
    题目大意给定集合a,求最大的是大小超过一半的子集的最大公约数的数是什么。题解“超过一半”即想到随机化n次后只有\(\frac{1}{2^n}\)的几率错误,于是随机一个数判断它的......
  • 题解 P3306 [SDOI2013] 随机数生成器
    Link它\(p\)都是质数了,这不就明示我们是bsgs了吗我没看出来然后我们来倒一下\(n\)天的式子第一天是\(x_1\),第二天是\(ax_1+b\),第三天是\(a^2x_1+(ab+b)\),第四......
  • 【题解】CF1264D2
    题目大意给定一个长度为\(n\)的字符串,其中只有(,),?三种字符,其中?可以为(或者)对于一个括号序列,定义其权值为其通过删除字符后可以得到的合法的括号匹配的最深的深度,下......