题意:要求在平面直角坐标系下维护两个操作:

1.在平面上加入一条线段。记第i条被插入的线段的标号为i。 
2.给定一个数k,询问与直线 x = k相交的线段中,交点最靠上的线段的编号。

解题关键:注意标志的作用,注意虽然存的是索引,但是线段树的范围是天数的范围,也就是线段树是依据天数建的树

复杂度:$O(nlogn)$

 #include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<iostream>
using namespace std;
typedef long long ll;
const int N=;
double a[N],b[N],ans;
int tr[N<<];
bool check(int x,int y,int t){
return a[x]+b[x]*(t-)>a[y]+b[y]*(t-);
} void update(int rt,int l,int r,int now){
if(l==r){
if(check(now,tr[rt],l)) tr[rt]=now;
return;
}
int mid=(l+r)>>;
if(b[now]>b[tr[rt]]){
if(check(now, tr[rt], mid)) update(rt<<,l, mid, tr[rt]),tr[rt]=now;//更新的最后一个是tr[rt]?存的是下标,询问时肯定按log的顺序,而此时now的掌控区间已经确定,需要更新tr[rt]的掌控区间
else update(rt<<|, mid+, r, now);
}
else{
if(check(now,tr[rt],mid)) update(rt<<|, mid+, r, tr[rt]),tr[rt]=now;
else update(rt<<, l, mid, now);
}
} void query(int rt,int l,int r,int now){
ans=max(ans,a[tr[rt]]+b[tr[rt]]*(now-));
if(l==r) return;
int mid=(l+r)>>;
if(now<=mid) query(rt<<, l, mid, now);
else query(rt<<|, mid+, r, now);
} int main(){
int n,m=,c;
char s[];
scanf("%d",&n);
for(int i=;i<n;i++){
scanf("%s",s);
if(s[]=='P'){
m++;
scanf("%lf%lf",a+m,b+m);
update(, ,n, m);//线段树中存的是下标,而值需要计算
}else{
scanf("%d",&c);
ans=;
query(, ,n, c);
printf("%d\n",(int)ans/);
}
}
return ;
}

模板2:主要是query函数的两种写法,此写法不需要建全局变量

 #include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<iostream>
using namespace std;
typedef long long ll;
const int N=;
double a[N],b[N],ans;
int tr[N<<];
bool check(int x,int y,int t){
return a[x]+b[x]*(t-)>a[y]+b[y]*(t-);
} void update(int rt,int l,int r,int now){
if(l==r){
if(check(now,tr[rt],l)) tr[rt]=now;
return;
}
int mid=(l+r)>>;
if(b[now]>b[tr[rt]]){
if(check(now, tr[rt], mid)) update(rt<<,l, mid, tr[rt]),tr[rt]=now;//更新的最后一个是tr[rt]?存的是下标,询问时肯定按log的顺序,而此时now的掌控区间已经确定,需要更新tr[rt]的掌控区间
else update(rt<<|, mid+, r, now);
}
else{
if(check(now,tr[rt],mid)) update(rt<<|, mid+, r, tr[rt]),tr[rt]=now;
else update(rt<<, l, mid, now);
}
} double query(int rt,int l,int r,int now){
double ans=max(0.0,a[tr[rt]]+b[tr[rt]]*(now-));
if(l==r) return ans;
int mid=(l+r)>>;
if(now<=mid) ans=max(ans,query(rt<<, l, mid, now));
else ans=max(ans,query(rt<<|, mid+, r, now));
return ans;
} int main(){
int n,m=,c;
char s[];
scanf("%d",&n);
for(int i=;i<n;i++){
scanf("%s",s);
if(s[]=='P'){
m++;
scanf("%lf%lf",a+m,b+m);
update(, ,n, m);//线段树中存的是下标,而值需要计算
}else{
scanf("%d",&c);
double ans=query(, ,n, c);
printf("%d\n",(int)ans/);
}
}
return ;
}

[bzoj1568]李超线段树模板题(标志永久化)的更多相关文章

  1. [AHOI 2009] 维护序列(线段树模板题)

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MB Description 老师交给小可可一个维护数列的任务,现在小 ...

  2. hdu1823(二维线段树模板题)

    hdu1823 题意 单点更新,求二维区间最值. 分析 二维线段树模板题. 二维线段树实际上就是树套树,即每个结点都要再建一颗线段树,维护对应的信息. 一般一维线段树是切割某一可变区间直到满足所要查询 ...

  3. [POJ2104] 区间第k大数 [区间第k大数,可持久化线段树模板题]

    可持久化线段树模板题. #include <iostream> #include <algorithm> #include <cstdio> #include &l ...

  4. HDU 1698 Just a Hook (线段树模板题-区间求和)

    Just a Hook In the game of DotA, Pudge’s meat hook is actually the most horrible thing for most of t ...

  5. UESTC - 1057 秋实大哥与花 线段树模板题

    http://acm.uestc.edu.cn/#/problem/show/1057 题意:给你n个数,q次操作,每次在l,r上加上x并输出此区间的sum 题解:线段树模板, #define _CR ...

  6. POJ - 3264 线段树模板题 询问区间最大最小值

    这是线段树的一个模板题,给出一串数字,然后询问区间的最大最小值. 这个其实很好办,只需把线段树的节点给出两个权值,一个是区间的最小值,一个是区间的最大值,初始化为负无穷和正无穷,然后通过不断地输入节点 ...

  7. 敌兵布阵 HDU - 1166 (树状数组模板题,线段树模板题)

    思路:就是树状数组的模板题,利用的就是单点更新和区间求和是树状数组的强项时间复杂度为m*log(n) 没想到自己以前把这道题当线段树的单点更新刷了. 树状数组: #include<iostrea ...

  8. zkw线段树模板题

    学了zkw线段树,觉得没什么必要刷专题的吧(切不动啊).. 那先放一个模板题吧(我绝不会和你说搬了一道树状数组模板题的!!!) 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某一个数加 ...

  9. P1243~P1247 线段树模板题总结

    前言 这几天刚刚刷了5道线段树(水)题,现在来总结一下. 首先是犯的不少错误: 1.建树.更新函数没有return.这是最气的,每次最后程序错误查了半天也没查出来,最后发现是没有return.递归边界 ...

随机推荐

  1. hadoop 根据secondary namenode恢复namenode

    refer to http://www.cnblogs.com/Richardzhu/p/3435989.html http://blog.csdn.net/wuzhilon88/article/de ...

  2. Data Structure Stack: Reverse a stack using recursion

    http://www.geeksforgeeks.org/reverse-a-stack-using-recursion/ #include <iostream> #include < ...

  3. vue双向绑定补充说明方法

    本文总结自: https://segmentfault.com/a/1190000006599500,将每一个流程提炼出来做一个简单的说明,以免自己被繁杂的逻辑弄昏头脑~ observer: 遍历数据 ...

  4. sqoop导入增量数据

    使用sqoop导入增量数据. 核心参数 --check-column 用来指定一些列,这些列在增量导入时用来检查这些数据是否作为增量数据进行导入,和关系行数据库中的自增字段及时间戳类似这些被指定的列的 ...

  5. JavaWeb -- 会话, Cookie 和 Session

    1. 会话 •Cookie是客户端技术,服务器把每个用户的数据以cookie的形式写给用户各自的浏览器.当用户使用浏览器再去访问服务器中的web资源时,就会带着各自的数据去.这样,web资源处理的就是 ...

  6. QT 按键处理 快捷键处理 shift + ctrl

    原味地址:http://www.cnblogs.com/codingmylife/archive/2010/08/30/1812739.html CTRL+Enter发送信息的实现 在现在的即时聊天程 ...

  7. maven建ssh项目的pom文件

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...

  8. jQuery - 获取/设置内容和属性

    获得内容 - text().html() 以及 val() 三个简单实用的用于 DOM 操作的 jQuery 方法: text() - 设置或返回所选元素的文本内容 html() - 设置或返回所选元 ...

  9. error: reference to 'max' is ambiguous

    1.     自定义的变量名    与      库中的      重名了

  10. leetcode 6 ZigZag Conversion(水题)

    就是简单的模拟一下就可以了.但是我一开始是用一个二维char数组来存的,这样在最终扫全体时会扫很多空的位置,浪费了很多时间,所以就time limit error了. 所以改进一下就用string数组 ...